mirror of https://github.com/mgba-emu/mgba.git
Core: Revamp tile cache, add untested map cache
This commit is contained in:
parent
a8f2990614
commit
df9616c15c
|
@ -0,0 +1,35 @@
|
|||
/* Copyright (c) 2013-2017 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_CACHE_SET_H
|
||||
#define M_CACHE_SET_H
|
||||
|
||||
#include <mgba-util/common.h>
|
||||
|
||||
CXX_GUARD_START
|
||||
|
||||
#include <mgba/core/map-cache.h>
|
||||
#include <mgba/core/tile-cache.h>
|
||||
#include <mgba-util/vector.h>
|
||||
|
||||
DECLARE_VECTOR(mMapCacheSet, struct mMapCache);
|
||||
DECLARE_VECTOR(mTileCacheSet, struct mTileCache);
|
||||
|
||||
struct mCacheSet {
|
||||
struct mMapCacheSet maps;
|
||||
struct mTileCacheSet tiles;
|
||||
};
|
||||
|
||||
void mCacheSetInit(struct mCacheSet*, size_t nMaps, size_t nTiles);
|
||||
void mCacheSetDeinit(struct mCacheSet*);
|
||||
|
||||
void mCacheSetAssignVRAM(struct mCacheSet*, void* vram);
|
||||
|
||||
void mCacheSetWriteVRAM(struct mCacheSet*, uint32_t address);
|
||||
void mCacheSetWritePalette(struct mCacheSet*, uint32_t entry, color_t color);
|
||||
|
||||
CXX_GUARD_END
|
||||
|
||||
#endif
|
|
@ -47,10 +47,7 @@ static inline color_t mColorFrom555(uint16_t value) {
|
|||
color_t color = value;
|
||||
#endif
|
||||
#else
|
||||
color_t color = 0;
|
||||
color |= (value << 3) & 0xF8;
|
||||
color |= (value << 6) & 0xF800;
|
||||
color |= (value << 9) & 0xF80000;
|
||||
color_t color = M_RGB5_TO_BGR8(value);
|
||||
color |= (color >> 5) & 0x070707;
|
||||
#endif
|
||||
return color;
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
/* Copyright (c) 2013-2017 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_MAP_CACHE_H
|
||||
#define M_MAP_CACHE_H
|
||||
|
||||
#include <mgba-util/common.h>
|
||||
|
||||
CXX_GUARD_START
|
||||
|
||||
#include <mgba/core/interface.h>
|
||||
|
||||
DECL_BITFIELD(mMapCacheConfiguration, uint32_t);
|
||||
DECL_BIT(mMapCacheConfiguration, ShouldStore, 0);
|
||||
|
||||
DECL_BITFIELD(mMapCacheSystemInfo, uint32_t);
|
||||
DECL_BITS(mMapCacheSystemInfo, PaletteBPP, 0, 2);
|
||||
DECL_BITS(mMapCacheSystemInfo, PaletteCount, 2, 4);
|
||||
DECL_BITS(mMapCacheSystemInfo, TilesWide, 8, 4);
|
||||
DECL_BITS(mMapCacheSystemInfo, TilesHigh, 12, 4);
|
||||
DECL_BITS(mMapCacheSystemInfo, MaxTiles, 16, 13);
|
||||
DECL_BITS(mMapCacheSystemInfo, MapAlign, 29, 2);
|
||||
|
||||
DECL_BITFIELD(mMapCacheEntryFlags, uint16_t);
|
||||
DECL_BITS(mMapCacheEntryFlags, PaletteId, 0, 4);
|
||||
DECL_BIT(mMapCacheEntryFlags, VramClean, 4);
|
||||
DECL_BIT(mMapCacheEntryFlags, HMirror, 5);
|
||||
DECL_BIT(mMapCacheEntryFlags, VMirror, 6);
|
||||
|
||||
struct mMapCacheEntry {
|
||||
uint32_t vramVersion;
|
||||
uint16_t tileId;
|
||||
mMapCacheEntryFlags flags;
|
||||
};
|
||||
|
||||
struct mTileCache;
|
||||
struct mTileCacheEntry;
|
||||
struct mMapCache {
|
||||
color_t* cache;
|
||||
struct mTileCache* tileCache;
|
||||
struct mTileCacheEntry* tileEntries;
|
||||
struct mMapCacheEntry* status;
|
||||
|
||||
uint8_t* vram;
|
||||
|
||||
uint32_t mapStart;
|
||||
uint32_t mapSize;
|
||||
|
||||
uint32_t tileStart;
|
||||
|
||||
mMapCacheConfiguration config;
|
||||
mMapCacheSystemInfo sysConfig;
|
||||
|
||||
void (*mapParser)(struct mMapCache*, struct mMapCacheEntry* entry, void* vram);
|
||||
};
|
||||
|
||||
void mMapCacheInit(struct mMapCache* cache);
|
||||
void mMapCacheDeinit(struct mMapCache* cache);
|
||||
void mMapCacheConfigure(struct mMapCache* cache, mMapCacheConfiguration config);
|
||||
void mMapCacheConfigureSystem(struct mMapCache* cache, mMapCacheSystemInfo config);
|
||||
void mMapCacheConfigureMap(struct mMapCache* cache, uint32_t mapStart);
|
||||
void mMapCacheWriteVRAM(struct mMapCache* cache, uint32_t address);
|
||||
|
||||
bool mMapCacheCheckTile(struct mMapCache* cache, const struct mMapCacheEntry* entry, unsigned x, unsigned y);
|
||||
void mMapCacheCleanTile(struct mMapCache* cache, struct mMapCacheEntry* entry, unsigned x, unsigned y);
|
||||
|
||||
CXX_GUARD_END
|
||||
|
||||
#endif
|
|
@ -10,14 +10,14 @@
|
|||
|
||||
CXX_GUARD_START
|
||||
|
||||
#include <mgba/core/interface.h>
|
||||
|
||||
DECL_BITFIELD(mTileCacheConfiguration, uint32_t);
|
||||
DECL_BIT(mTileCacheConfiguration, ShouldStore, 0);
|
||||
|
||||
DECL_BITFIELD(mTileCacheSystemInfo, uint32_t);
|
||||
DECL_BITS(mTileCacheSystemInfo, Palette0BPP, 0, 2);
|
||||
DECL_BITS(mTileCacheSystemInfo, Palette0Count, 2, 4);
|
||||
DECL_BITS(mTileCacheSystemInfo, Palette1BPP, 8, 2);
|
||||
DECL_BITS(mTileCacheSystemInfo, Palette1Count, 10, 4);
|
||||
DECL_BITS(mTileCacheSystemInfo, PaletteBPP, 0, 2);
|
||||
DECL_BITS(mTileCacheSystemInfo, PaletteCount, 2, 4);
|
||||
DECL_BITS(mTileCacheSystemInfo, MaxTiles, 16, 13);
|
||||
|
||||
struct mTileCacheEntry {
|
||||
|
@ -25,24 +25,22 @@ struct mTileCacheEntry {
|
|||
uint32_t vramVersion;
|
||||
uint8_t vramClean;
|
||||
uint8_t paletteId;
|
||||
uint8_t activePalette;
|
||||
uint8_t padding;
|
||||
uint16_t padding;
|
||||
};
|
||||
|
||||
struct mTileCache {
|
||||
uint16_t* cache;
|
||||
color_t* cache;
|
||||
struct mTileCacheEntry* status;
|
||||
uint32_t* globalPaletteVersion[2];
|
||||
uint32_t* globalPaletteVersion;
|
||||
|
||||
int activePalette;
|
||||
unsigned entries;
|
||||
unsigned count;
|
||||
uint32_t tileBase;
|
||||
uint32_t paletteBase;
|
||||
unsigned entriesPerTile;
|
||||
unsigned bpp;
|
||||
|
||||
uint16_t* vram;
|
||||
uint16_t* palette;
|
||||
uint16_t temporaryTile[64];
|
||||
color_t* palette;
|
||||
color_t temporaryTile[64];
|
||||
|
||||
mTileCacheConfiguration config;
|
||||
mTileCacheSystemInfo sysConfig;
|
||||
|
@ -51,15 +49,14 @@ struct mTileCache {
|
|||
void mTileCacheInit(struct mTileCache* cache);
|
||||
void mTileCacheDeinit(struct mTileCache* cache);
|
||||
void mTileCacheConfigure(struct mTileCache* cache, mTileCacheConfiguration config);
|
||||
void mTileCacheConfigureSystem(struct mTileCache* cache, mTileCacheSystemInfo config);
|
||||
void mTileCacheConfigureSystem(struct mTileCache* cache, mTileCacheSystemInfo config, uint32_t tileBase, uint32_t paletteBase);
|
||||
void mTileCacheWriteVRAM(struct mTileCache* cache, uint32_t address);
|
||||
void mTileCacheWritePalette(struct mTileCache* cache, uint32_t address);
|
||||
void mTileCacheSetPalette(struct mTileCache* cache, int palette);
|
||||
void mTileCacheWritePalette(struct mTileCache* cache, uint32_t entry, color_t color);
|
||||
|
||||
const uint16_t* mTileCacheGetTile(struct mTileCache* cache, unsigned tileId, unsigned paletteId);
|
||||
const uint16_t* mTileCacheGetTileIfDirty(struct mTileCache* cache, struct mTileCacheEntry* entry, unsigned tileId, unsigned paletteId);
|
||||
const uint8_t* mTileCacheGetRawTile(struct mTileCache* cache, unsigned tileId);
|
||||
const uint16_t* mTileCacheGetPalette(struct mTileCache* cache, unsigned paletteId);
|
||||
const color_t* mTileCacheGetTile(struct mTileCache* cache, unsigned tileId, unsigned paletteId);
|
||||
const color_t* mTileCacheGetTileIfDirty(struct mTileCache* cache, struct mTileCacheEntry* entry, unsigned tileId, unsigned paletteId);
|
||||
const color_t* mTileCacheGetPalette(struct mTileCache* cache, unsigned paletteId);
|
||||
const uint16_t* mTileCacheGetVRAM(struct mTileCache* cache, unsigned tileId);
|
||||
|
||||
CXX_GUARD_END
|
||||
|
||||
|
|
|
@ -11,10 +11,10 @@
|
|||
CXX_GUARD_START
|
||||
|
||||
struct GBVideo;
|
||||
struct mTileCache;
|
||||
struct mCacheSet;
|
||||
|
||||
void GBVideoTileCacheInit(struct mTileCache* cache);
|
||||
void GBVideoTileCacheAssociate(struct mTileCache* cache, struct GBVideo* video);
|
||||
void GBVideoCacheInit(struct mCacheSet* cache);
|
||||
void GBVideoCacheAssociate(struct mCacheSet* cache, struct GBVideo* video);
|
||||
|
||||
CXX_GUARD_END
|
||||
|
|
@ -65,7 +65,7 @@ union GBOAM {
|
|||
uint8_t raw[160];
|
||||
};
|
||||
|
||||
struct mTileCache;
|
||||
struct mCacheSet;
|
||||
struct GBVideoRenderer {
|
||||
void (*init)(struct GBVideoRenderer* renderer, enum GBModel model, bool borders);
|
||||
void (*deinit)(struct GBVideoRenderer* renderer);
|
||||
|
@ -84,7 +84,7 @@ struct GBVideoRenderer {
|
|||
|
||||
uint8_t* vram;
|
||||
union GBOAM* oam;
|
||||
struct mTileCache* cache;
|
||||
struct mCacheSet* cache;
|
||||
|
||||
uint8_t* sgbCharRam;
|
||||
uint8_t* sgbMapRam;
|
||||
|
|
|
@ -3,18 +3,19 @@
|
|||
* 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 GBA_TILE_CACHE_H
|
||||
#define GBA_TILE_CACHE_H
|
||||
#ifndef GBA_CACHE_SET_H
|
||||
#define GBA_CACHE_SET_H
|
||||
|
||||
#include <mgba-util/common.h>
|
||||
|
||||
CXX_GUARD_START
|
||||
|
||||
struct GBAVideo;
|
||||
struct mTileCache;
|
||||
struct mCacheSet;
|
||||
|
||||
void GBAVideoTileCacheInit(struct mTileCache* cache);
|
||||
void GBAVideoTileCacheAssociate(struct mTileCache* cache, struct GBAVideo* video);
|
||||
void GBAVideoCacheInit(struct mCacheSet* cache);
|
||||
void GBAVideoCacheAssociate(struct mCacheSet* cache, struct GBAVideo* video);
|
||||
void GBAVideoCacheWriteVideoRegister(struct mCacheSet* cache, uint32_t address, uint16_t value);
|
||||
|
||||
CXX_GUARD_END
|
||||
|
|
@ -164,7 +164,7 @@ struct GBAVideoRenderer {
|
|||
uint16_t* palette;
|
||||
uint16_t* vram;
|
||||
union GBAOAM* oam;
|
||||
struct mTileCache* cache;
|
||||
struct mCacheSet* cache;
|
||||
|
||||
bool disableBG[4];
|
||||
bool disableOBJ;
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
/* Copyright (c) 2013-2017 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/cache-set.h>
|
||||
|
||||
DEFINE_VECTOR(mMapCacheSet, struct mMapCache);
|
||||
DEFINE_VECTOR(mTileCacheSet, struct mTileCache);
|
||||
|
||||
void mCacheSetInit(struct mCacheSet* cache, size_t nMaps, size_t nTiles) {
|
||||
mMapCacheSetInit(&cache->maps, nMaps);
|
||||
mMapCacheSetResize(&cache->maps, nMaps);
|
||||
mTileCacheSetInit(&cache->tiles, nTiles);
|
||||
mTileCacheSetResize(&cache->tiles, nTiles);
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < nMaps; ++i) {
|
||||
mMapCacheInit(mMapCacheSetGetPointer(&cache->maps, i));
|
||||
}
|
||||
for (i = 0; i < nTiles; ++i) {
|
||||
mTileCacheInit(mTileCacheSetGetPointer(&cache->tiles, i));
|
||||
}
|
||||
}
|
||||
|
||||
void mCacheSetDeinit(struct mCacheSet* cache) {
|
||||
size_t i;
|
||||
for (i = 0; i < mMapCacheSetSize(&cache->maps); ++i) {
|
||||
mMapCacheDeinit(mMapCacheSetGetPointer(&cache->maps, i));
|
||||
}
|
||||
for (i = 0; i < mTileCacheSetSize(&cache->tiles); ++i) {
|
||||
mTileCacheDeinit(mTileCacheSetGetPointer(&cache->tiles, i));
|
||||
}
|
||||
}
|
||||
|
||||
void mCacheSetAssignVRAM(struct mCacheSet* cache, void* vram) {
|
||||
size_t i;
|
||||
for (i = 0; i < mMapCacheSetSize(&cache->maps); ++i) {
|
||||
mMapCacheSetGetPointer(&cache->maps, 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);
|
||||
}
|
||||
}
|
||||
|
||||
void mCacheSetWriteVRAM(struct mCacheSet* cache, uint32_t address) {
|
||||
size_t i;
|
||||
for (i = 0; i < mMapCacheSetSize(&cache->maps); ++i) {
|
||||
mMapCacheWriteVRAM(mMapCacheSetGetPointer(&cache->maps, i), address);
|
||||
}
|
||||
for (i = 0; i < mTileCacheSetSize(&cache->tiles); ++i) {
|
||||
mTileCacheWriteVRAM(mTileCacheSetGetPointer(&cache->tiles, i), address);
|
||||
}
|
||||
}
|
||||
|
||||
void mCacheSetWritePalette(struct mCacheSet* cache, uint32_t entry, color_t color) {
|
||||
size_t i;
|
||||
for (i = 0; i < mTileCacheSetSize(&cache->tiles); ++i) {
|
||||
mTileCacheWritePalette(mTileCacheSetGetPointer(&cache->tiles, i), entry, color);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
/* Copyright (c) 2013-2017 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/map-cache.h>
|
||||
|
||||
#include <mgba/core/tile-cache.h>
|
||||
#include <mgba-util/memory.h>
|
||||
|
||||
void mMapCacheInit(struct mMapCache* cache) {
|
||||
// TODO: Reconfigurable cache for space savings
|
||||
cache->cache = NULL;
|
||||
cache->config = mMapCacheConfigurationFillShouldStore(0);
|
||||
cache->status = NULL;
|
||||
}
|
||||
|
||||
static void _freeCache(struct mMapCache* cache) {
|
||||
size_t tiles = (1 << mMapCacheSystemInfoGetTilesWide(cache->sysConfig)) * (1 << mMapCacheSystemInfoGetTilesHigh(cache->sysConfig));
|
||||
mappedMemoryFree(cache->cache, 8 * 8 * sizeof(color_t) * tiles);
|
||||
mappedMemoryFree(cache->status, tiles * sizeof(*cache->status));
|
||||
cache->cache = NULL;
|
||||
cache->status = NULL;
|
||||
}
|
||||
|
||||
static void _redoCacheSize(struct mMapCache* cache) {
|
||||
if (!mMapCacheConfigurationIsShouldStore(cache->config)) {
|
||||
return;
|
||||
}
|
||||
|
||||
size_t tiles = (1 << mMapCacheSystemInfoGetTilesWide(cache->sysConfig)) * (1 << mMapCacheSystemInfoGetTilesHigh(cache->sysConfig));
|
||||
cache->cache = anonymousMemoryMap(8 * 8 * sizeof(color_t) * tiles);
|
||||
cache->status = anonymousMemoryMap(tiles * sizeof(*cache->status));
|
||||
}
|
||||
|
||||
void mMapCacheConfigure(struct mMapCache* cache, mMapCacheConfiguration config) {
|
||||
_freeCache(cache);
|
||||
cache->config = config;
|
||||
_redoCacheSize(cache);
|
||||
}
|
||||
|
||||
void mMapCacheConfigureSystem(struct mMapCache* cache, mMapCacheSystemInfo config) {
|
||||
_freeCache(cache);
|
||||
cache->sysConfig = config;
|
||||
_redoCacheSize(cache);
|
||||
|
||||
size_t mapSize = (1 << mMapCacheSystemInfoGetTilesWide(cache->sysConfig)) * (1 << mMapCacheSystemInfoGetTilesHigh(cache->sysConfig));
|
||||
cache->mapSize = mapSize << mMapCacheSystemInfoGetMapAlign(cache->sysConfig);
|
||||
}
|
||||
|
||||
void mMapCacheConfigureMap(struct mMapCache* cache, uint32_t mapStart) {
|
||||
size_t tiles = (1 << mMapCacheSystemInfoGetTilesWide(cache->sysConfig)) * (1 << mMapCacheSystemInfoGetTilesHigh(cache->sysConfig));
|
||||
memset(cache->status, 0, tiles * sizeof(*cache->status));
|
||||
cache->mapStart = mapStart;
|
||||
}
|
||||
|
||||
void mMapCacheDeinit(struct mMapCache* cache) {
|
||||
_freeCache(cache);
|
||||
}
|
||||
|
||||
void mMapCacheWriteVRAM(struct mMapCache* cache, uint32_t address) {
|
||||
if (address >= cache->mapStart && address < cache->mapStart + cache->mapSize) {
|
||||
address >>= mMapCacheSystemInfoGetMapAlign(cache->sysConfig);
|
||||
++cache->status[address].vramVersion;
|
||||
cache->status[address].flags = mMapCacheEntryFlagsClearVramClean(cache->status[address].flags);
|
||||
}
|
||||
}
|
||||
|
||||
bool mMapCacheCheckTile(struct mMapCache* cache, const struct mMapCacheEntry* entry, unsigned x, unsigned y) {
|
||||
size_t location = (1 << mMapCacheSystemInfoGetTilesWide(cache->sysConfig)) * y + x;
|
||||
const struct mMapCacheEntry* status = &cache->status[location];
|
||||
return memcmp(status, &entry[location], sizeof(*entry)) == 0;
|
||||
}
|
||||
|
||||
void mMapCacheCleanTile(struct mMapCache* cache, struct mMapCacheEntry* entry, unsigned x, unsigned y) {
|
||||
size_t location = (1 << mMapCacheSystemInfoGetTilesWide(cache->sysConfig)) * y + x;
|
||||
struct mMapCacheEntry* status = &cache->status[location];
|
||||
status->flags = mMapCacheEntryFlagsFillVramClean(status->flags);
|
||||
int align = mMapCacheSystemInfoGetMapAlign(cache->sysConfig);
|
||||
cache->mapParser(cache, status, &cache->vram[(location << align) + cache->mapStart]);
|
||||
|
||||
int bytesPerPixel = 1 << mMapCacheSystemInfoGetPaletteBPP(cache->sysConfig);
|
||||
size_t stride = bytesPerPixel * (1 << mMapCacheSystemInfoGetTilesWide(cache->sysConfig));
|
||||
color_t* mapOut = &cache->cache[(y * stride + x) * 8];
|
||||
const color_t* tile = mTileCacheGetTileIfDirty(cache->tileCache, cache->tileEntries, status->tileId + cache->tileStart, mMapCacheEntryFlagsGetPaletteId(status->flags));
|
||||
memcpy(mapOut, tile, sizeof(color_t) * 8);
|
||||
memcpy(&mapOut[stride], &tile[0x08], sizeof(color_t) * 8);
|
||||
memcpy(&mapOut[stride * 2], &tile[0x10], sizeof(color_t) * 8);
|
||||
memcpy(&mapOut[stride * 3], &tile[0x18], sizeof(color_t) * 8);
|
||||
memcpy(&mapOut[stride * 4], &tile[0x20], sizeof(color_t) * 8);
|
||||
memcpy(&mapOut[stride * 5], &tile[0x28], sizeof(color_t) * 8);
|
||||
memcpy(&mapOut[stride * 6], &tile[0x30], sizeof(color_t) * 8);
|
||||
memcpy(&mapOut[stride * 7], &tile[0x38], sizeof(color_t) * 8);
|
||||
|
||||
entry[location] = *status;
|
||||
}
|
|
@ -12,60 +12,42 @@ void mTileCacheInit(struct mTileCache* cache) {
|
|||
cache->cache = NULL;
|
||||
cache->config = mTileCacheConfigurationFillShouldStore(0);
|
||||
cache->status = NULL;
|
||||
cache->activePalette = 0;
|
||||
memset(cache->globalPaletteVersion, 0, sizeof(cache->globalPaletteVersion));
|
||||
cache->globalPaletteVersion = NULL;
|
||||
cache->palette = NULL;
|
||||
}
|
||||
|
||||
static void _freeCache(struct mTileCache* cache) {
|
||||
unsigned count0;
|
||||
count0 = 1 << mTileCacheSystemInfoGetPalette0Count(cache->sysConfig);
|
||||
unsigned count1;
|
||||
count1 = 1 << mTileCacheSystemInfoGetPalette1Count(cache->sysConfig);
|
||||
unsigned size = 1 << mTileCacheSystemInfoGetPaletteCount(cache->sysConfig);
|
||||
unsigned tiles = mTileCacheSystemInfoGetMaxTiles(cache->sysConfig);
|
||||
unsigned size = count0 > count1 ? count0 : count1;
|
||||
if (cache->cache) {
|
||||
mappedMemoryFree(cache->cache, 8 * 8 * 2 * tiles * size);
|
||||
mappedMemoryFree(cache->cache, 8 * 8 * sizeof(color_t) * tiles * size);
|
||||
cache->cache = NULL;
|
||||
}
|
||||
if (cache->status) {
|
||||
mappedMemoryFree(cache->status, tiles * size * sizeof(*cache->status));
|
||||
cache->status = NULL;
|
||||
}
|
||||
free(cache->globalPaletteVersion[0]);
|
||||
free(cache->globalPaletteVersion[1]);
|
||||
memset(cache->globalPaletteVersion, 0, sizeof(cache->globalPaletteVersion));
|
||||
free(cache->globalPaletteVersion);
|
||||
cache->globalPaletteVersion = NULL;
|
||||
free(cache->palette);
|
||||
cache->palette = NULL;
|
||||
}
|
||||
|
||||
static void _redoCacheSize(struct mTileCache* cache) {
|
||||
if (!mTileCacheConfigurationIsShouldStore(cache->config)) {
|
||||
return;
|
||||
}
|
||||
unsigned count0 = mTileCacheSystemInfoGetPalette0Count(cache->sysConfig);
|
||||
unsigned bpp0 = mTileCacheSystemInfoGetPalette0BPP(cache->sysConfig);
|
||||
bpp0 = 1 << (1 << bpp0);
|
||||
if (count0) {
|
||||
count0 = 1 << count0;
|
||||
}
|
||||
unsigned count1 = mTileCacheSystemInfoGetPalette1Count(cache->sysConfig);
|
||||
unsigned bpp1 = mTileCacheSystemInfoGetPalette1BPP(cache->sysConfig);
|
||||
bpp1 = 1 << (1 << bpp1);
|
||||
if (count1) {
|
||||
count1 = 1 << count1;
|
||||
}
|
||||
unsigned size = count0 > count1 ? count0 : count1;
|
||||
if (!size) {
|
||||
return;
|
||||
}
|
||||
unsigned size = mTileCacheSystemInfoGetPaletteCount(cache->sysConfig);
|
||||
unsigned bpp = mTileCacheSystemInfoGetPaletteBPP(cache->sysConfig);
|
||||
cache->bpp = bpp;
|
||||
bpp = 1 << (1 << bpp);
|
||||
size = 1 << size;
|
||||
cache->entriesPerTile = size;
|
||||
unsigned tiles = mTileCacheSystemInfoGetMaxTiles(cache->sysConfig);
|
||||
cache->cache = anonymousMemoryMap(8 * 8 * 2 * tiles * size);
|
||||
cache->cache = anonymousMemoryMap(8 * 8 * sizeof(color_t) * tiles * size);
|
||||
cache->status = anonymousMemoryMap(tiles * size * sizeof(*cache->status));
|
||||
if (count0) {
|
||||
cache->globalPaletteVersion[0] = malloc(count0 * bpp0 * sizeof(*cache->globalPaletteVersion[0]));
|
||||
}
|
||||
if (count1) {
|
||||
cache->globalPaletteVersion[1] = malloc(count1 * bpp1 * sizeof(*cache->globalPaletteVersion[1]));
|
||||
}
|
||||
cache->globalPaletteVersion = malloc(size * sizeof(*cache->globalPaletteVersion));
|
||||
cache->palette = malloc(size * bpp * sizeof(*cache->palette));
|
||||
}
|
||||
|
||||
void mTileCacheConfigure(struct mTileCache* cache, mTileCacheConfiguration config) {
|
||||
|
@ -74,9 +56,11 @@ void mTileCacheConfigure(struct mTileCache* cache, mTileCacheConfiguration confi
|
|||
_redoCacheSize(cache);
|
||||
}
|
||||
|
||||
void mTileCacheConfigureSystem(struct mTileCache* cache, mTileCacheSystemInfo config) {
|
||||
void mTileCacheConfigureSystem(struct mTileCache* cache, mTileCacheSystemInfo config, uint32_t tileBase, uint32_t paletteBase) {
|
||||
_freeCache(cache);
|
||||
cache->sysConfig = config;
|
||||
cache->tileBase = tileBase;
|
||||
cache->paletteBase = paletteBase;
|
||||
_redoCacheSize(cache);
|
||||
}
|
||||
|
||||
|
@ -85,40 +69,41 @@ void mTileCacheDeinit(struct mTileCache* cache) {
|
|||
}
|
||||
|
||||
void mTileCacheWriteVRAM(struct mTileCache* cache, uint32_t address) {
|
||||
if (address < cache->tileBase) {
|
||||
return;
|
||||
}
|
||||
address -= cache->tileBase;
|
||||
unsigned bpp = cache->bpp + 3;
|
||||
unsigned count = cache->entriesPerTile;
|
||||
address >>= bpp;
|
||||
if (address >= mTileCacheSystemInfoGetMaxTiles(cache->sysConfig)) {
|
||||
return;
|
||||
}
|
||||
size_t i;
|
||||
for (i = 0; i < count; ++i) {
|
||||
cache->status[(address >> bpp) * count + i].vramClean = 0;
|
||||
++cache->status[(address >> bpp) * count + i].vramVersion;
|
||||
cache->status[address * count + i].vramClean = 0;
|
||||
++cache->status[address * count + i].vramVersion;
|
||||
}
|
||||
}
|
||||
|
||||
void mTileCacheWritePalette(struct mTileCache* cache, uint32_t address) {
|
||||
if (cache->globalPaletteVersion[0]) {
|
||||
++cache->globalPaletteVersion[0][address >> 1];
|
||||
void mTileCacheWritePalette(struct mTileCache* cache, uint32_t entry, color_t color) {
|
||||
if (entry < cache->paletteBase) {
|
||||
return;
|
||||
}
|
||||
if (cache->globalPaletteVersion[1]) {
|
||||
++cache->globalPaletteVersion[1][address >> 1];
|
||||
entry -= cache->paletteBase;
|
||||
unsigned maxEntry = (1 << (1 << cache->bpp)) * cache->entriesPerTile;
|
||||
if (entry >= maxEntry) {
|
||||
return;
|
||||
}
|
||||
cache->palette[entry] = color;
|
||||
entry >>= (1 << mTileCacheSystemInfoGetPaletteBPP(cache->sysConfig));
|
||||
++cache->globalPaletteVersion[entry];
|
||||
}
|
||||
|
||||
void mTileCacheSetPalette(struct mTileCache* cache, int palette) {
|
||||
cache->activePalette = palette;
|
||||
if (palette == 0) {
|
||||
cache->bpp = mTileCacheSystemInfoGetPalette0BPP(cache->sysConfig);
|
||||
cache->count = 1 << mTileCacheSystemInfoGetPalette0Count(cache->sysConfig);
|
||||
} else {
|
||||
cache->bpp = mTileCacheSystemInfoGetPalette1BPP(cache->sysConfig);
|
||||
cache->count = 1 << mTileCacheSystemInfoGetPalette1Count(cache->sysConfig);
|
||||
}
|
||||
cache->entries = 1 << (1 << cache->bpp);
|
||||
}
|
||||
|
||||
static void _regenerateTile4(struct mTileCache* cache, uint16_t* tile, unsigned tileId, unsigned paletteId) {
|
||||
static void _regenerateTile4(struct mTileCache* cache, color_t* tile, unsigned tileId, unsigned paletteId) {
|
||||
uint8_t* start = (uint8_t*) &cache->vram[tileId << 3];
|
||||
paletteId <<= 2;
|
||||
uint16_t* palette = &cache->palette[paletteId];
|
||||
color_t* palette = &cache->palette[paletteId];
|
||||
int i;
|
||||
for (i = 0; i < 8; ++i) {
|
||||
uint8_t tileDataLower = start[0];
|
||||
|
@ -126,87 +111,87 @@ static void _regenerateTile4(struct mTileCache* cache, uint16_t* tile, unsigned
|
|||
start += 2;
|
||||
int pixel;
|
||||
pixel = ((tileDataUpper & 128) >> 6) | ((tileDataLower & 128) >> 7);
|
||||
tile[0] = pixel ? palette[pixel] | 0x8000 : palette[pixel] & 0x7FFF;
|
||||
tile[0] = pixel ? palette[pixel] | 0xFF000000 : palette[pixel];
|
||||
pixel = ((tileDataUpper & 64) >> 5) | ((tileDataLower & 64) >> 6);
|
||||
tile[1] = pixel ? palette[pixel] | 0x8000 : palette[pixel] & 0x7FFF;
|
||||
tile[1] = pixel ? palette[pixel] | 0xFF000000 : palette[pixel];
|
||||
pixel = ((tileDataUpper & 32) >> 4) | ((tileDataLower & 32) >> 5);
|
||||
tile[2] = pixel ? palette[pixel] | 0x8000 : palette[pixel] & 0x7FFF;
|
||||
tile[2] = pixel ? palette[pixel] | 0xFF000000 : palette[pixel];
|
||||
pixel = ((tileDataUpper & 16) >> 3) | ((tileDataLower & 16) >> 4);
|
||||
tile[3] = pixel ? palette[pixel] | 0x8000 : palette[pixel] & 0x7FFF;
|
||||
tile[3] = pixel ? palette[pixel] | 0xFF000000 : palette[pixel];
|
||||
pixel = ((tileDataUpper & 8) >> 2) | ((tileDataLower & 8) >> 3);
|
||||
tile[4] = pixel ? palette[pixel] | 0x8000 : palette[pixel] & 0x7FFF;
|
||||
tile[4] = pixel ? palette[pixel] | 0xFF000000 : palette[pixel];
|
||||
pixel = ((tileDataUpper & 4) >> 1) | ((tileDataLower & 4) >> 2);
|
||||
tile[5] = pixel ? palette[pixel] | 0x8000 : palette[pixel] & 0x7FFF;
|
||||
tile[5] = pixel ? palette[pixel] | 0xFF000000 : palette[pixel];
|
||||
pixel = (tileDataUpper & 2) | ((tileDataLower & 2) >> 1);
|
||||
tile[6] = pixel ? palette[pixel] | 0x8000 : palette[pixel] & 0x7FFF;
|
||||
tile[6] = pixel ? palette[pixel] | 0xFF000000 : palette[pixel];
|
||||
pixel = ((tileDataUpper & 1) << 1) | (tileDataLower & 1);
|
||||
tile[7] = pixel ? palette[pixel] | 0x8000 : palette[pixel] & 0x7FFF;
|
||||
tile[7] = pixel ? palette[pixel] | 0xFF000000 : palette[pixel];
|
||||
tile += 8;
|
||||
}
|
||||
}
|
||||
|
||||
static void _regenerateTile16(struct mTileCache* cache, uint16_t* tile, unsigned tileId, unsigned paletteId) {
|
||||
static void _regenerateTile16(struct mTileCache* cache, color_t* tile, unsigned tileId, unsigned paletteId) {
|
||||
uint32_t* start = (uint32_t*) &cache->vram[tileId << 4];
|
||||
paletteId <<= 4;
|
||||
uint16_t* palette = &cache->palette[paletteId];
|
||||
color_t* palette = &cache->palette[paletteId];
|
||||
int i;
|
||||
for (i = 0; i < 8; ++i) {
|
||||
uint32_t line = *start;
|
||||
++start;
|
||||
int pixel;
|
||||
pixel = line & 0xF;
|
||||
tile[0] = pixel ? palette[pixel] | 0x8000 : palette[pixel] & 0x7FFF;
|
||||
tile[0] = pixel ? palette[pixel] | 0xFF000000 : palette[pixel];
|
||||
pixel = (line >> 4) & 0xF;
|
||||
tile[1] = pixel ? palette[pixel] | 0x8000 : palette[pixel] & 0x7FFF;
|
||||
tile[1] = pixel ? palette[pixel] | 0xFF000000 : palette[pixel];
|
||||
pixel = (line >> 8) & 0xF;
|
||||
tile[2] = pixel ? palette[pixel] | 0x8000 : palette[pixel] & 0x7FFF;
|
||||
tile[2] = pixel ? palette[pixel] | 0xFF000000 : palette[pixel];
|
||||
pixel = (line >> 12) & 0xF;
|
||||
tile[3] = pixel ? palette[pixel] | 0x8000 : palette[pixel] & 0x7FFF;
|
||||
tile[3] = pixel ? palette[pixel] | 0xFF000000 : palette[pixel];
|
||||
pixel = (line >> 16) & 0xF;
|
||||
tile[4] = pixel ? palette[pixel] | 0x8000 : palette[pixel] & 0x7FFF;
|
||||
tile[4] = pixel ? palette[pixel] | 0xFF000000 : palette[pixel];
|
||||
pixel = (line >> 20) & 0xF;
|
||||
tile[5] = pixel ? palette[pixel] | 0x8000 : palette[pixel] & 0x7FFF;
|
||||
tile[5] = pixel ? palette[pixel] | 0xFF000000 : palette[pixel];
|
||||
pixel = (line >> 24) & 0xF;
|
||||
tile[6] = pixel ? palette[pixel] | 0x8000 : palette[pixel] & 0x7FFF;
|
||||
tile[6] = pixel ? palette[pixel] | 0xFF000000 : palette[pixel];
|
||||
pixel = (line >> 28) & 0xF;
|
||||
tile[7] = pixel ? palette[pixel] | 0x8000 : palette[pixel] & 0x7FFF;
|
||||
tile[7] = pixel ? palette[pixel] | 0xFF000000 : palette[pixel];
|
||||
tile += 8;
|
||||
}
|
||||
}
|
||||
|
||||
static void _regenerateTile256(struct mTileCache* cache, uint16_t* tile, unsigned tileId, unsigned paletteId) {
|
||||
static void _regenerateTile256(struct mTileCache* cache, color_t* tile, unsigned tileId, unsigned paletteId) {
|
||||
uint32_t* start = (uint32_t*) &cache->vram[tileId << 5];
|
||||
paletteId <<= 8;
|
||||
uint16_t* palette = &cache->palette[paletteId];
|
||||
color_t* palette = &cache->palette[paletteId];
|
||||
int i;
|
||||
for (i = 0; i < 8; ++i) {
|
||||
uint32_t line = *start;
|
||||
++start;
|
||||
int pixel;
|
||||
pixel = line & 0xFF;
|
||||
tile[0] = pixel ? palette[pixel] | 0x8000 : palette[pixel] & 0x7FFF;
|
||||
tile[0] = pixel ? palette[pixel] | 0xFF000000 : palette[pixel];
|
||||
pixel = (line >> 8) & 0xFF;
|
||||
tile[1] = pixel ? palette[pixel] | 0x8000 : palette[pixel] & 0x7FFF;
|
||||
tile[1] = pixel ? palette[pixel] | 0xFF000000 : palette[pixel];
|
||||
pixel = (line >> 16) & 0xFF;
|
||||
tile[2] = pixel ? palette[pixel] | 0x8000 : palette[pixel] & 0x7FFF;
|
||||
tile[2] = pixel ? palette[pixel] | 0xFF000000 : palette[pixel];
|
||||
pixel = (line >> 24) & 0xFF;
|
||||
tile[3] = pixel ? palette[pixel] | 0x8000 : palette[pixel] & 0x7FFF;
|
||||
tile[3] = pixel ? palette[pixel] | 0xFF000000 : palette[pixel];
|
||||
|
||||
line = *start;
|
||||
++start;
|
||||
pixel = line & 0xFF;
|
||||
tile[4] = pixel ? palette[pixel] | 0x8000 : palette[pixel] & 0x7FFF;
|
||||
tile[4] = pixel ? palette[pixel] | 0xFF000000 : palette[pixel];
|
||||
pixel = (line >> 8) & 0xFF;
|
||||
tile[5] = pixel ? palette[pixel] | 0x8000 : palette[pixel] & 0x7FFF;
|
||||
tile[5] = pixel ? palette[pixel] | 0xFF000000 : palette[pixel];
|
||||
pixel = (line >> 16) & 0xFF;
|
||||
tile[6] = pixel ? palette[pixel] | 0x8000 : palette[pixel] & 0x7FFF;
|
||||
tile[6] = pixel ? palette[pixel] | 0xFF000000 : palette[pixel];
|
||||
pixel = (line >> 24) & 0xFF;
|
||||
tile[7] = pixel ? palette[pixel] | 0x8000 : palette[pixel] & 0x7FFF;
|
||||
tile[7] = pixel ? palette[pixel] | 0xFF000000 : palette[pixel];
|
||||
tile += 8;
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint16_t* _tileLookup(struct mTileCache* cache, unsigned tileId, unsigned paletteId) {
|
||||
static inline color_t* _tileLookup(struct mTileCache* cache, unsigned tileId, unsigned paletteId) {
|
||||
if (mTileCacheConfigurationIsShouldStore(cache->config)) {
|
||||
unsigned tiles = mTileCacheSystemInfoGetMaxTiles(cache->sysConfig);
|
||||
return &cache->cache[(tileId + paletteId * tiles) << 6];
|
||||
|
@ -215,19 +200,17 @@ static inline uint16_t* _tileLookup(struct mTileCache* cache, unsigned tileId, u
|
|||
}
|
||||
}
|
||||
|
||||
const uint16_t* mTileCacheGetTile(struct mTileCache* cache, unsigned tileId, unsigned paletteId) {
|
||||
unsigned cPaletteId = cache->activePalette;
|
||||
const color_t* mTileCacheGetTile(struct mTileCache* cache, unsigned tileId, unsigned paletteId) {
|
||||
unsigned count = cache->entriesPerTile;
|
||||
unsigned bpp = cache->bpp;
|
||||
struct mTileCacheEntry* status = &cache->status[tileId * count + paletteId];
|
||||
struct mTileCacheEntry desiredStatus = {
|
||||
.paletteVersion = cache->globalPaletteVersion[cPaletteId][paletteId],
|
||||
.paletteVersion = cache->globalPaletteVersion[paletteId],
|
||||
.vramVersion = status->vramVersion,
|
||||
.vramClean = 1,
|
||||
.paletteId = paletteId,
|
||||
.activePalette = cPaletteId
|
||||
.paletteId = paletteId
|
||||
};
|
||||
uint16_t* tile = _tileLookup(cache, tileId, paletteId);
|
||||
color_t* tile = _tileLookup(cache, tileId, paletteId);
|
||||
if (!mTileCacheConfigurationIsShouldStore(cache->config) || memcmp(status, &desiredStatus, sizeof(*status))) {
|
||||
switch (bpp) {
|
||||
case 0:
|
||||
|
@ -247,19 +230,17 @@ const uint16_t* mTileCacheGetTile(struct mTileCache* cache, unsigned tileId, uns
|
|||
return tile;
|
||||
}
|
||||
|
||||
const uint16_t* mTileCacheGetTileIfDirty(struct mTileCache* cache, struct mTileCacheEntry* entry, unsigned tileId, unsigned paletteId) {
|
||||
unsigned cPaletteId = cache->activePalette;
|
||||
const color_t* mTileCacheGetTileIfDirty(struct mTileCache* cache, struct mTileCacheEntry* entry, unsigned tileId, unsigned paletteId) {
|
||||
unsigned count = cache->entriesPerTile;
|
||||
unsigned bpp = cache->bpp;
|
||||
struct mTileCacheEntry* status = &cache->status[tileId * count + paletteId];
|
||||
struct mTileCacheEntry desiredStatus = {
|
||||
.paletteVersion = cache->globalPaletteVersion[cPaletteId][paletteId],
|
||||
.paletteVersion = cache->globalPaletteVersion[paletteId],
|
||||
.vramVersion = status->vramVersion,
|
||||
.vramClean = 1,
|
||||
.paletteId = paletteId,
|
||||
.activePalette = cPaletteId
|
||||
.paletteId = paletteId
|
||||
};
|
||||
uint16_t* tile = NULL;
|
||||
color_t* tile = NULL;
|
||||
if (memcmp(status, &desiredStatus, sizeof(*status))) {
|
||||
tile = _tileLookup(cache, tileId, paletteId);
|
||||
switch (bpp) {
|
||||
|
@ -284,26 +265,10 @@ const uint16_t* mTileCacheGetTileIfDirty(struct mTileCache* cache, struct mTileC
|
|||
return tile;
|
||||
}
|
||||
|
||||
const uint8_t* mTileCacheGetRawTile(struct mTileCache* cache, unsigned tileId) {
|
||||
unsigned bpp = cache->bpp;
|
||||
switch (bpp) {
|
||||
case 0:
|
||||
return NULL;
|
||||
default:
|
||||
return (uint8_t*) &cache->vram[tileId << (2 + bpp)];
|
||||
}
|
||||
const color_t* mTileCacheGetPalette(struct mTileCache* cache, unsigned paletteId) {
|
||||
return &cache->palette[paletteId << (1 << cache->bpp)];
|
||||
}
|
||||
|
||||
const uint16_t* mTileCacheGetPalette(struct mTileCache* cache, unsigned paletteId) {
|
||||
unsigned bpp = cache->bpp;
|
||||
switch (bpp) {
|
||||
default:
|
||||
return NULL;
|
||||
case 1:
|
||||
return &cache->palette[paletteId << 2];
|
||||
case 2:
|
||||
return &cache->palette[paletteId << 4];
|
||||
case 3:
|
||||
return &cache->palette[paletteId << 8];
|
||||
}
|
||||
const uint16_t* mTileCacheGetVRAM(struct mTileCache* cache, unsigned tileId) {
|
||||
return &cache->vram[tileId << (cache->bpp + 2)];
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#include <mgba/internal/gb/renderers/proxy.h>
|
||||
|
||||
#include <mgba/core/tile-cache.h>
|
||||
#include <mgba/core/cache-set.h>
|
||||
#include <mgba/internal/gb/gb.h>
|
||||
#include <mgba/internal/gb/io.h>
|
||||
|
||||
|
@ -203,7 +203,7 @@ void GBVideoProxyRendererWriteVRAM(struct GBVideoRenderer* renderer, uint16_t ad
|
|||
proxyRenderer->backend->writeVRAM(proxyRenderer->backend, address);
|
||||
}
|
||||
if (renderer->cache) {
|
||||
mTileCacheWriteVRAM(renderer->cache, address);
|
||||
mCacheSetWriteVRAM(renderer->cache, address);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -214,7 +214,7 @@ void GBVideoProxyRendererWritePalette(struct GBVideoRenderer* renderer, int addr
|
|||
proxyRenderer->backend->writePalette(proxyRenderer->backend, address, value);
|
||||
}
|
||||
if (renderer->cache) {
|
||||
mTileCacheWritePalette(renderer->cache, address);
|
||||
mCacheSetWritePalette(renderer->cache, address, mColorFrom555(value));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
/* Copyright (c) 2013-2017 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/internal/gb/renderers/cache-set.h>
|
||||
|
||||
#include <mgba/core/cache-set.h>
|
||||
#include <mgba/internal/gb/video.h>
|
||||
|
||||
void GBVideoCacheInit(struct mCacheSet* cache) {
|
||||
mCacheSetInit(cache, 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);
|
||||
}
|
||||
|
||||
void GBVideoCacheAssociate(struct mCacheSet* cache, struct GBVideo* video) {
|
||||
mCacheSetAssignVRAM(cache, video->vram);
|
||||
video->renderer->cache = cache;
|
||||
size_t i;
|
||||
for (i = 0; i < 64; ++i) {
|
||||
mCacheSetWritePalette(cache, i, mColorFrom555(video->palette[i]));
|
||||
}
|
||||
}
|
|
@ -5,7 +5,7 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#include <mgba/internal/gb/renderers/software.h>
|
||||
|
||||
#include <mgba/core/tile-cache.h>
|
||||
#include <mgba/core/cache-set.h>
|
||||
#include <mgba/internal/gb/io.h>
|
||||
#include <mgba-util/math.h>
|
||||
#include <mgba-util/memory.h>
|
||||
|
@ -284,13 +284,13 @@ static void GBVideoSoftwareRendererWritePalette(struct GBVideoRenderer* renderer
|
|||
color_t color = mColorFrom555(value);
|
||||
softwareRenderer->palette[index] = color;
|
||||
if (renderer->cache) {
|
||||
mTileCacheWritePalette(renderer->cache, index << 1);
|
||||
mCacheSetWritePalette(renderer->cache, index, color);
|
||||
}
|
||||
}
|
||||
|
||||
static void GBVideoSoftwareRendererWriteVRAM(struct GBVideoRenderer* renderer, uint16_t address) {
|
||||
if (renderer->cache) {
|
||||
mTileCacheWriteVRAM(renderer->cache, address);
|
||||
mCacheSetWriteVRAM(renderer->cache, address);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
/* Copyright (c) 2013-2016 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/internal/gb/renderers/tile-cache.h>
|
||||
|
||||
#include <mgba/core/tile-cache.h>
|
||||
#include <mgba/internal/gb/video.h>
|
||||
#include <mgba/internal/gb/renderers/tile-cache.h>
|
||||
|
||||
void GBVideoTileCacheInit(struct mTileCache* cache) {
|
||||
mTileCacheInit(cache);
|
||||
mTileCacheConfiguration config = 0;
|
||||
config = mTileCacheSystemInfoSetPalette0BPP(config, 1); // 2^(2^2) = 4 entries
|
||||
config = mTileCacheSystemInfoSetPalette0Count(config, 4); // 16 palettes
|
||||
config = mTileCacheSystemInfoSetPalette1BPP(config, 0); // Disable
|
||||
config = mTileCacheSystemInfoSetPalette1Count(config, 0); // Disable
|
||||
config = mTileCacheSystemInfoSetMaxTiles(config, 1024);
|
||||
mTileCacheConfigureSystem(cache, config);
|
||||
}
|
||||
|
||||
void GBVideoTileCacheAssociate(struct mTileCache* cache, struct GBVideo* video) {
|
||||
cache->vram = (uint16_t*) video->vram;
|
||||
cache->palette = video->palette;
|
||||
video->renderer->cache = cache;
|
||||
}
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
#include <mgba/core/sync.h>
|
||||
#include <mgba/core/thread.h>
|
||||
#include <mgba/core/tile-cache.h>
|
||||
#include <mgba/core/cache-set.h>
|
||||
#include <mgba/internal/gb/gb.h>
|
||||
#include <mgba/internal/gb/io.h>
|
||||
#include <mgba/internal/gb/serialize.h>
|
||||
|
@ -705,7 +705,7 @@ static void GBVideoDummyRendererWriteSGBPacket(struct GBVideoRenderer* renderer,
|
|||
|
||||
static void GBVideoDummyRendererWriteVRAM(struct GBVideoRenderer* renderer, uint16_t address) {
|
||||
if (renderer->cache) {
|
||||
mTileCacheWriteVRAM(renderer->cache, address);
|
||||
mCacheSetWriteVRAM(renderer->cache, address);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -716,9 +716,8 @@ static void GBVideoDummyRendererWriteOAM(struct GBVideoRenderer* renderer, uint1
|
|||
}
|
||||
|
||||
static void GBVideoDummyRendererWritePalette(struct GBVideoRenderer* renderer, int index, uint16_t value) {
|
||||
UNUSED(value);
|
||||
if (renderer->cache) {
|
||||
mTileCacheWritePalette(renderer->cache, index << 1);
|
||||
mCacheSetWritePalette(renderer->cache, index, mColorFrom555(value));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#include <mgba/internal/gba/renderers/proxy.h>
|
||||
|
||||
#include <mgba/core/tile-cache.h>
|
||||
#include <mgba/core/cache-set.h>
|
||||
#include <mgba/internal/gba/gba.h>
|
||||
#include <mgba/internal/gba/io.h>
|
||||
|
||||
|
@ -206,7 +206,7 @@ void GBAVideoProxyRendererWriteVRAM(struct GBAVideoRenderer* renderer, uint32_t
|
|||
proxyRenderer->backend->writeVRAM(proxyRenderer->backend, address);
|
||||
}
|
||||
if (renderer->cache) {
|
||||
mTileCacheWriteVRAM(renderer->cache, address);
|
||||
mCacheSetWriteVRAM(renderer->cache, address);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -217,7 +217,7 @@ void GBAVideoProxyRendererWritePalette(struct GBAVideoRenderer* renderer, uint32
|
|||
proxyRenderer->backend->writePalette(proxyRenderer->backend, address, value);
|
||||
}
|
||||
if (renderer->cache) {
|
||||
mTileCacheWritePalette(renderer->cache, address);
|
||||
mCacheSetWritePalette(renderer->cache, address >> 1, mColorFrom555(value));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,158 @@
|
|||
/* Copyright (c) 2013-2017 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/internal/gba/renderers/cache-set.h>
|
||||
|
||||
#include <mgba/core/cache-set.h>
|
||||
#include <mgba/internal/gba/gba.h>
|
||||
#include <mgba/internal/gba/io.h>
|
||||
#include <mgba/internal/gba/video.h>
|
||||
|
||||
void GBAVideoCacheInit(struct mCacheSet* cache) {
|
||||
mCacheSetInit(cache, 4, 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));
|
||||
}
|
||||
|
||||
void GBAVideoCacheAssociate(struct mCacheSet* cache, struct GBAVideo* video) {
|
||||
mCacheSetAssignVRAM(cache, video->vram);
|
||||
video->renderer->cache = cache;
|
||||
size_t i;
|
||||
for (i = 0; i < SIZE_PALETTE_RAM / 2; ++i) {
|
||||
mCacheSetWritePalette(cache, i, mColorFrom555(video->palette[i]));
|
||||
}
|
||||
}
|
||||
|
||||
static void mapParser0(struct mMapCache* cache, struct mMapCacheEntry* entry, void* vram) {
|
||||
UNUSED(cache);
|
||||
uint16_t map = *(uint16_t*) vram;
|
||||
entry->tileId = GBA_TEXT_MAP_TILE(map);
|
||||
entry->flags = mMapCacheEntryFlagsSetHMirror(entry->flags, GBA_TEXT_MAP_HFLIP(map));
|
||||
entry->flags = mMapCacheEntryFlagsSetHMirror(entry->flags, GBA_TEXT_MAP_VFLIP(map));
|
||||
entry->flags = mMapCacheEntryFlagsSetPaletteId(entry->flags, GBA_TEXT_MAP_PALETTE(map));
|
||||
}
|
||||
|
||||
static void mapParser2(struct mMapCache* cache, struct mMapCacheEntry* entry, void* vram) {
|
||||
UNUSED(cache);
|
||||
entry->tileId = *(uint8_t*) vram;
|
||||
entry->flags = mMapCacheEntryFlagsClearHMirror(entry->flags);
|
||||
entry->flags = mMapCacheEntryFlagsClearHMirror(entry->flags);
|
||||
entry->flags = mMapCacheEntryFlagsClearPaletteId(entry->flags);
|
||||
}
|
||||
|
||||
static void GBAVideoCacheWriteDISPCNT(struct mCacheSet* cache, uint16_t value) {
|
||||
switch (GBARegisterDISPCNTGetMode(value)) {
|
||||
case 0:
|
||||
default:
|
||||
mMapCacheSetGetPointer(&cache->maps, 0)->mapParser = mapParser0;
|
||||
mMapCacheSetGetPointer(&cache->maps, 1)->mapParser = mapParser0;
|
||||
mMapCacheSetGetPointer(&cache->maps, 2)->mapParser = mapParser0;
|
||||
mMapCacheSetGetPointer(&cache->maps, 3)->mapParser = mapParser0;
|
||||
|
||||
mMapCacheSetGetPointer(&cache->maps, 0)->tileCache = mTileCacheSetGetPointer(&cache->tiles, 0);
|
||||
mMapCacheSetGetPointer(&cache->maps, 1)->tileCache = mTileCacheSetGetPointer(&cache->tiles, 0);
|
||||
mMapCacheSetGetPointer(&cache->maps, 2)->tileCache = mTileCacheSetGetPointer(&cache->tiles, 0);
|
||||
mMapCacheSetGetPointer(&cache->maps, 3)->tileCache = mTileCacheSetGetPointer(&cache->tiles, 0);
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
mMapCacheSetGetPointer(&cache->maps, 0)->mapParser = mapParser0;
|
||||
mMapCacheSetGetPointer(&cache->maps, 1)->mapParser = mapParser0;
|
||||
mMapCacheSetGetPointer(&cache->maps, 2)->mapParser = mapParser2;
|
||||
mMapCacheSetGetPointer(&cache->maps, 3)->mapParser = mapParser2;
|
||||
|
||||
mMapCacheSetGetPointer(&cache->maps, 0)->tileCache = mTileCacheSetGetPointer(&cache->tiles, 1);
|
||||
mMapCacheSetGetPointer(&cache->maps, 1)->tileCache = mTileCacheSetGetPointer(&cache->tiles, 1);
|
||||
mMapCacheSetGetPointer(&cache->maps, 2)->tileCache = mTileCacheSetGetPointer(&cache->tiles, 1);
|
||||
mMapCacheSetGetPointer(&cache->maps, 3)->tileCache = mTileCacheSetGetPointer(&cache->tiles, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void GBAVideoCacheWriteBGCNT(struct mCacheSet* cache, size_t bg, uint16_t value) {
|
||||
struct mMapCache* map = mMapCacheSetGetPointer(&cache->maps, bg);
|
||||
|
||||
int tileStart = GBARegisterBGCNTGetCharBase(value) * 128;
|
||||
bool p = GBARegisterBGCNTGet256Color(value);
|
||||
mMapCacheConfigureMap(map, GBARegisterBGCNTGetScreenBase(value) << 11);
|
||||
int size = GBARegisterBGCNTGetSize(value);
|
||||
int tilesWide = 0;
|
||||
int tilesHigh = 0;
|
||||
mMapCacheSystemInfo sysconfig = 0;
|
||||
if (map->mapParser == mapParser0) {
|
||||
sysconfig = mMapCacheSystemInfoSetPaletteBPP(sysconfig, 2 + p);
|
||||
sysconfig = mMapCacheSystemInfoSetPaletteCount(sysconfig, 4 * !p);
|
||||
sysconfig = mMapCacheSystemInfoSetMaxTiles(sysconfig, 512);
|
||||
sysconfig = mMapCacheSystemInfoSetMapAlign(sysconfig, 1);
|
||||
tilesWide = 5;
|
||||
tilesHigh = 5;
|
||||
if (size & 1) {
|
||||
++tilesWide;
|
||||
}
|
||||
if (size & 2) {
|
||||
++tilesHigh;
|
||||
}
|
||||
map->tileStart = tileStart * 2;
|
||||
} else if (map->mapParser == mapParser2) {
|
||||
sysconfig = mMapCacheSystemInfoSetPaletteBPP(sysconfig, 3);
|
||||
sysconfig = mMapCacheSystemInfoSetPaletteCount(sysconfig, 0);
|
||||
sysconfig = mMapCacheSystemInfoSetMaxTiles(sysconfig, 256);
|
||||
sysconfig = mMapCacheSystemInfoSetMapAlign(sysconfig, 0);
|
||||
|
||||
tilesHigh = 4 + size;
|
||||
tilesWide = 4 + size;
|
||||
map->tileStart = tileStart;
|
||||
}
|
||||
sysconfig = mMapCacheSystemInfoSetTilesHigh(sysconfig, tilesHigh);
|
||||
sysconfig = mMapCacheSystemInfoSetTilesWide(sysconfig, tilesWide);
|
||||
mMapCacheConfigureSystem(map, sysconfig);
|
||||
}
|
||||
|
||||
void GBAVideoCacheWriteVideoRegister(struct mCacheSet* cache, uint32_t address, uint16_t value) {
|
||||
switch (address) {
|
||||
case REG_DISPCNT:
|
||||
GBAVideoCacheWriteDISPCNT(cache, value);
|
||||
break;
|
||||
case REG_BG0CNT:
|
||||
GBAVideoCacheWriteBGCNT(cache, 0, value);
|
||||
break;
|
||||
case REG_BG1CNT:
|
||||
GBAVideoCacheWriteBGCNT(cache, 1, value);
|
||||
break;
|
||||
case REG_BG2CNT:
|
||||
GBAVideoCacheWriteBGCNT(cache, 2, value);
|
||||
break;
|
||||
case REG_BG3CNT:
|
||||
GBAVideoCacheWriteBGCNT(cache, 3, value);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
/* Copyright (c) 2013-2016 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/internal/gba/renderers/tile-cache.h>
|
||||
|
||||
#include <mgba/core/tile-cache.h>
|
||||
#include <mgba/internal/gba/video.h>
|
||||
|
||||
void GBAVideoTileCacheInit(struct mTileCache* cache) {
|
||||
mTileCacheInit(cache);
|
||||
mTileCacheConfiguration config = 0;
|
||||
config = mTileCacheSystemInfoSetPalette0BPP(config, 2); // 2^(2^2) = 16 entries
|
||||
config = mTileCacheSystemInfoSetPalette0Count(config, 5); // 32 palettes
|
||||
config = mTileCacheSystemInfoSetPalette1BPP(config, 3); // 2^(2^3) = 256 entries
|
||||
config = mTileCacheSystemInfoSetPalette1Count(config, 1); // 2 palettes
|
||||
config = mTileCacheSystemInfoSetMaxTiles(config, 3072);
|
||||
mTileCacheConfigureSystem(cache, config);
|
||||
}
|
||||
|
||||
void GBAVideoTileCacheAssociate(struct mTileCache* cache, struct GBAVideo* video) {
|
||||
cache->vram = video->vram;
|
||||
cache->palette = video->palette;
|
||||
video->renderer->cache = cache;
|
||||
}
|
|
@ -5,9 +5,10 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#include "gba/renderers/software-private.h"
|
||||
|
||||
#include <mgba/core/tile-cache.h>
|
||||
#include <mgba/core/cache-set.h>
|
||||
#include <mgba/internal/arm/macros.h>
|
||||
#include <mgba/internal/gba/io.h>
|
||||
#include <mgba/internal/gba/renderers/cache-set.h>
|
||||
|
||||
#include <mgba-util/arm-algo.h>
|
||||
#include <mgba-util/memory.h>
|
||||
|
@ -149,6 +150,10 @@ static void GBAVideoSoftwareRendererDeinit(struct GBAVideoRenderer* renderer) {
|
|||
|
||||
static uint16_t GBAVideoSoftwareRendererWriteVideoRegister(struct GBAVideoRenderer* renderer, uint32_t address, uint16_t value) {
|
||||
struct GBAVideoSoftwareRenderer* softwareRenderer = (struct GBAVideoSoftwareRenderer*) renderer;
|
||||
if (renderer->cache) {
|
||||
GBAVideoCacheWriteVideoRegister(renderer->cache, address, value);
|
||||
}
|
||||
|
||||
switch (address) {
|
||||
case REG_DISPCNT:
|
||||
softwareRenderer->dispcnt = value;
|
||||
|
@ -381,7 +386,7 @@ static uint16_t GBAVideoSoftwareRendererWriteVideoRegister(struct GBAVideoRender
|
|||
static void GBAVideoSoftwareRendererWriteVRAM(struct GBAVideoRenderer* renderer, uint32_t address) {
|
||||
struct GBAVideoSoftwareRenderer* softwareRenderer = (struct GBAVideoSoftwareRenderer*) renderer;
|
||||
if (renderer->cache) {
|
||||
mTileCacheWriteVRAM(renderer->cache, address);
|
||||
mCacheSetWriteVRAM(renderer->cache, address);
|
||||
}
|
||||
memset(softwareRenderer->scanlineDirty, 0xFFFFFFFF, sizeof(softwareRenderer->scanlineDirty));
|
||||
}
|
||||
|
@ -403,7 +408,7 @@ static void GBAVideoSoftwareRendererWritePalette(struct GBAVideoRenderer* render
|
|||
softwareRenderer->variantPalette[address >> 1] = _darken(color, softwareRenderer->bldy);
|
||||
}
|
||||
if (renderer->cache) {
|
||||
mTileCacheWritePalette(renderer->cache, address);
|
||||
mCacheSetWritePalette(renderer->cache, address >> 1, color);
|
||||
}
|
||||
memset(softwareRenderer->scanlineDirty, 0xFFFFFFFF, sizeof(softwareRenderer->scanlineDirty));
|
||||
}
|
||||
|
|
|
@ -6,11 +6,12 @@
|
|||
#include <mgba/internal/gba/video.h>
|
||||
|
||||
#include <mgba/core/sync.h>
|
||||
#include <mgba/core/tile-cache.h>
|
||||
#include <mgba/core/cache-set.h>
|
||||
#include <mgba/internal/arm/macros.h>
|
||||
#include <mgba/internal/gba/dma.h>
|
||||
#include <mgba/internal/gba/gba.h>
|
||||
#include <mgba/internal/gba/io.h>
|
||||
#include <mgba/internal/gba/renderers/cache-set.h>
|
||||
#include <mgba/internal/gba/serialize.h>
|
||||
|
||||
#include <mgba-util/memory.h>
|
||||
|
@ -214,7 +215,9 @@ static void GBAVideoDummyRendererDeinit(struct GBAVideoRenderer* renderer) {
|
|||
}
|
||||
|
||||
static uint16_t GBAVideoDummyRendererWriteVideoRegister(struct GBAVideoRenderer* renderer, uint32_t address, uint16_t value) {
|
||||
UNUSED(renderer);
|
||||
if (renderer->cache) {
|
||||
GBAVideoCacheWriteVideoRegister(renderer->cache, address, value);
|
||||
}
|
||||
switch (address) {
|
||||
case REG_BG0CNT:
|
||||
case REG_BG1CNT:
|
||||
|
@ -252,14 +255,13 @@ static uint16_t GBAVideoDummyRendererWriteVideoRegister(struct GBAVideoRenderer*
|
|||
|
||||
static void GBAVideoDummyRendererWriteVRAM(struct GBAVideoRenderer* renderer, uint32_t address) {
|
||||
if (renderer->cache) {
|
||||
mTileCacheWriteVRAM(renderer->cache, address);
|
||||
mCacheSetWriteVRAM(renderer->cache, address);
|
||||
}
|
||||
}
|
||||
|
||||
static void GBAVideoDummyRendererWritePalette(struct GBAVideoRenderer* renderer, uint32_t address, uint16_t value) {
|
||||
UNUSED(value);
|
||||
if (renderer->cache) {
|
||||
mTileCacheWritePalette(renderer->cache, address);
|
||||
mCacheSetWritePalette(renderer->cache, address >> 1, mColorFrom555(value));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ void free(void*);
|
|||
|
||||
#include <mgba/core/core.h>
|
||||
#include <mgba/core/mem-search.h>
|
||||
#include <mgba/core/tile-cache.h>
|
||||
#include <mgba/core/cache-set.h>
|
||||
#include <mgba/core/thread.h>
|
||||
#include <mgba/core/version.h>
|
||||
|
||||
|
@ -49,13 +49,13 @@ void free(void*);
|
|||
#include <mgba/internal/arm/arm.h>
|
||||
#include <mgba/internal/gba/gba.h>
|
||||
#include <mgba/internal/gba/input.h>
|
||||
#include <mgba/internal/gba/renderers/tile-cache.h>
|
||||
#include <mgba/internal/gba/renderers/cache-set.h>
|
||||
#endif
|
||||
#ifdef M_CORE_GB
|
||||
#include <mgba/internal/lr35902/lr35902.h>
|
||||
#include <mgba/internal/gb/gb.h>
|
||||
#include <mgba/internal/gba/input.h>
|
||||
#include <mgba/internal/gb/renderers/tile-cache.h>
|
||||
#include <mgba/internal/gb/renderers/cache-set.h>
|
||||
#endif
|
||||
#ifdef USE_DEBUGGERS
|
||||
#include <mgba/debugger/debugger.h>
|
||||
|
|
|
@ -24,17 +24,17 @@ ffi.set_source("mgba._pylib", """
|
|||
#include <mgba/core/log.h>
|
||||
#include <mgba/core/mem-search.h>
|
||||
#include <mgba/core/thread.h>
|
||||
#include <mgba/core/tile-cache.h>
|
||||
#include <mgba/core/cache-set.h>
|
||||
#include <mgba/core/version.h>
|
||||
#include <mgba/debugger/debugger.h>
|
||||
#include <mgba/internal/arm/arm.h>
|
||||
#include <mgba/internal/debugger/cli-debugger.h>
|
||||
#include <mgba/internal/gba/gba.h>
|
||||
#include <mgba/internal/gba/input.h>
|
||||
#include <mgba/internal/gba/renderers/tile-cache.h>
|
||||
#include <mgba/internal/gba/renderers/cache-set.h>
|
||||
#include <mgba/internal/lr35902/lr35902.h>
|
||||
#include <mgba/internal/gb/gb.h>
|
||||
#include <mgba/internal/gb/renderers/tile-cache.h>
|
||||
#include <mgba/internal/gb/renderers/cache-set.h>
|
||||
#include <mgba-util/png-io.h>
|
||||
#include <mgba-util/vfs.h>
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ AssetTile::AssetTile(QWidget* parent)
|
|||
}
|
||||
|
||||
void AssetTile::setController(std::shared_ptr<CoreController> controller) {
|
||||
m_tileCache = controller->tileCache();
|
||||
m_cacheSet = controller->graphicCaches();
|
||||
switch (controller->platform()) {
|
||||
#ifdef M_CORE_GBA
|
||||
case PLATFORM_GBA:
|
||||
|
@ -70,39 +70,32 @@ void AssetTile::setPalette(int palette) {
|
|||
selectIndex(m_index);
|
||||
}
|
||||
|
||||
void AssetTile::setPaletteSet(int palette, int boundary, int max) {
|
||||
m_index = m_index * (1 + m_paletteSet) / (1 + palette);
|
||||
if (m_index >= max) {
|
||||
m_index = max - 1;
|
||||
}
|
||||
void AssetTile::setBoundary(int boundary, int set0, int set1) {
|
||||
m_boundary = boundary;
|
||||
m_paletteSet = palette;
|
||||
selectIndex(m_index);
|
||||
m_tileCaches[0] = mTileCacheSetGetPointer(&m_cacheSet->tiles, set0);
|
||||
m_tileCaches[1] = mTileCacheSetGetPointer(&m_cacheSet->tiles, set1);
|
||||
}
|
||||
|
||||
void AssetTile::selectIndex(int index) {
|
||||
m_index = index;
|
||||
const uint16_t* data;
|
||||
const color_t* data;
|
||||
mTileCache* tileCache = m_tileCaches[index >= m_boundary];
|
||||
|
||||
mTileCacheSetPalette(m_tileCache, m_paletteSet);
|
||||
unsigned bpp = 8 << m_tileCache->bpp;
|
||||
int dispIndex = index;
|
||||
unsigned bpp = 8 << tileCache->bpp;
|
||||
int paletteId = m_paletteId;
|
||||
int base = m_addressBase;
|
||||
if (index >= m_boundary) {
|
||||
base = m_boundaryBase;
|
||||
// XXX: Do this better
|
||||
#ifdef M_CORE_GBA
|
||||
if (m_boundaryBase == (BASE_VRAM | 0x10000)) {
|
||||
paletteId += m_tileCache->count / 2;
|
||||
}
|
||||
#endif
|
||||
dispIndex -= m_boundary;
|
||||
index -= m_boundary;
|
||||
}
|
||||
data = mTileCacheGetTile(m_tileCache, index, paletteId);
|
||||
m_ui.tileId->setText(QString::number(dispIndex * (1 + m_paletteSet)));
|
||||
int dispIndex = index;
|
||||
if (m_addressWidth == 4 && index >= m_boundary / 2) {
|
||||
dispIndex -= m_boundary / 2;
|
||||
}
|
||||
data = mTileCacheGetTile(tileCache, index, paletteId);
|
||||
m_ui.tileId->setText(QString::number(dispIndex));
|
||||
m_ui.address->setText(tr("%0%1%2")
|
||||
.arg(m_addressWidth == 4 ? index >= m_boundary : 0)
|
||||
.arg(m_addressWidth == 4 ? index >= m_boundary / 2 : 0)
|
||||
.arg(m_addressWidth == 4 ? ":" : "x")
|
||||
.arg(dispIndex * bpp | base, m_addressWidth, 16, QChar('0')));
|
||||
for (int i = 0; i < 64; ++i) {
|
||||
|
@ -112,24 +105,18 @@ void AssetTile::selectIndex(int index) {
|
|||
}
|
||||
|
||||
void AssetTile::selectColor(int index) {
|
||||
const uint16_t* data;
|
||||
mTileCacheSetPalette(m_tileCache, m_paletteSet);
|
||||
unsigned bpp = 8 << m_tileCache->bpp;
|
||||
const color_t* data;
|
||||
mTileCache* tileCache = m_tileCaches[m_index >= m_boundary];
|
||||
unsigned bpp = 8 << tileCache->bpp;
|
||||
int paletteId = m_paletteId;
|
||||
// XXX: Do this better
|
||||
#ifdef M_CORE_GBA
|
||||
if (m_index >= m_boundary && m_boundaryBase == (BASE_VRAM | 0x10000)) {
|
||||
paletteId += m_tileCache->count / 2;
|
||||
}
|
||||
#endif
|
||||
data = mTileCacheGetTile(m_tileCache, m_index, m_paletteId);
|
||||
uint16_t color = data[index];
|
||||
data = mTileCacheGetTile(tileCache, m_index, m_paletteId);
|
||||
color_t color = data[index];
|
||||
m_ui.color->setColor(0, color);
|
||||
m_ui.color->update();
|
||||
|
||||
uint32_t r = M_R5(color);
|
||||
uint32_t g = M_G5(color);
|
||||
uint32_t b = M_B5(color);
|
||||
uint32_t r = color & 0xF8;
|
||||
uint32_t g = (color >> 8) & 0xF8;
|
||||
uint32_t b = (color >> 16) & 0xF8;
|
||||
m_ui.r->setText(tr("0x%0 (%1)").arg(r, 2, 16, QChar('0')).arg(r, 2, 10, QChar('0')));
|
||||
m_ui.g->setText(tr("0x%0 (%1)").arg(g, 2, 16, QChar('0')).arg(g, 2, 10, QChar('0')));
|
||||
m_ui.b->setText(tr("0x%0 (%1)").arg(b, 2, 16, QChar('0')).arg(b, 2, 10, QChar('0')));
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
#include <memory>
|
||||
|
||||
#include <mgba/core/tile-cache.h>
|
||||
#include <mgba/core/cache-set.h>
|
||||
|
||||
namespace QGBA {
|
||||
|
||||
|
@ -24,16 +24,16 @@ public:
|
|||
|
||||
public slots:
|
||||
void setPalette(int);
|
||||
void setPaletteSet(int, int boundary, int max);
|
||||
void setBoundary(int boundary, int set0, int set1);
|
||||
void selectIndex(int);
|
||||
void selectColor(int);
|
||||
|
||||
private:
|
||||
Ui::AssetTile m_ui;
|
||||
|
||||
mTileCache* m_tileCache;
|
||||
mCacheSet* m_cacheSet;
|
||||
mTileCache* m_tileCaches[2];
|
||||
int m_paletteId = 0;
|
||||
int m_paletteSet = 0;
|
||||
int m_index = 0;
|
||||
|
||||
int m_addressWidth;
|
||||
|
|
|
@ -13,7 +13,7 @@ using namespace QGBA;
|
|||
|
||||
AssetView::AssetView(std::shared_ptr<CoreController> controller, QWidget* parent)
|
||||
: QWidget(parent)
|
||||
, m_tileCache(controller->tileCache())
|
||||
, m_cacheSet(controller->graphicCaches())
|
||||
, m_controller(controller)
|
||||
{
|
||||
m_updateTimer.setSingleShot(true);
|
||||
|
@ -55,8 +55,8 @@ void AssetView::showEvent(QShowEvent*) {
|
|||
updateTiles(true);
|
||||
}
|
||||
|
||||
void AssetView::compositeTile(unsigned tileId, void* buffer, size_t stride, size_t x, size_t y, int depth) {
|
||||
const uint8_t* tile = mTileCacheGetRawTile(m_tileCache, tileId);
|
||||
void AssetView::compositeTile(const void* tBuffer, void* buffer, size_t stride, size_t x, size_t y, int depth) {
|
||||
const uint8_t* tile = static_cast<const uint8_t*>(tBuffer);
|
||||
uint8_t* pixels = static_cast<uint8_t*>(buffer);
|
||||
size_t base = stride * y + x;
|
||||
switch (depth) {
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
#include <QTimer>
|
||||
#include <QWidget>
|
||||
|
||||
#include <mgba/core/tile-cache.h>
|
||||
#include <mgba/core/cache-set.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
|
@ -22,7 +22,7 @@ Q_OBJECT
|
|||
public:
|
||||
AssetView(std::shared_ptr<CoreController> controller, QWidget* parent = nullptr);
|
||||
|
||||
void compositeTile(unsigned tileId, void* image, size_t stride, size_t x, size_t y, int depth = 8);
|
||||
static void compositeTile(const void* tile, void* image, size_t stride, size_t x, size_t y, int depth = 8);
|
||||
|
||||
protected slots:
|
||||
void updateTiles();
|
||||
|
@ -39,7 +39,7 @@ protected:
|
|||
void resizeEvent(QResizeEvent*) override;
|
||||
void showEvent(QShowEvent*) override;
|
||||
|
||||
mTileCache* const m_tileCache;
|
||||
mCacheSet* const m_cacheSet;
|
||||
|
||||
private:
|
||||
std::shared_ptr<CoreController> m_controller;
|
||||
|
|
|
@ -18,12 +18,12 @@
|
|||
#include <mgba/feature/video-logger.h>
|
||||
#ifdef M_CORE_GBA
|
||||
#include <mgba/internal/gba/gba.h>
|
||||
#include <mgba/internal/gba/renderers/tile-cache.h>
|
||||
#include <mgba/internal/gba/renderers/cache-set.h>
|
||||
#include <mgba/internal/gba/sharkport.h>
|
||||
#endif
|
||||
#ifdef M_CORE_GB
|
||||
#include <mgba/internal/gb/gb.h>
|
||||
#include <mgba/internal/gb/renderers/tile-cache.h>
|
||||
#include <mgba/internal/gb/renderers/cache-set.h>
|
||||
#endif
|
||||
#include <mgba-util/math.h>
|
||||
#include <mgba-util/vfs.h>
|
||||
|
@ -186,9 +186,9 @@ CoreController::~CoreController() {
|
|||
stop();
|
||||
disconnect();
|
||||
|
||||
if (m_tileCache) {
|
||||
mTileCacheDeinit(m_tileCache.get());
|
||||
m_tileCache.reset();
|
||||
if (m_cacheSet) {
|
||||
mCacheSetDeinit(m_cacheSet.get());
|
||||
m_cacheSet.reset();
|
||||
}
|
||||
|
||||
mCoreThreadJoin(&m_threadContext);
|
||||
|
@ -268,36 +268,34 @@ void CoreController::clearMultiplayerController() {
|
|||
m_multiplayer = nullptr;
|
||||
}
|
||||
|
||||
mTileCache* CoreController::tileCache() {
|
||||
if (m_tileCache) {
|
||||
return m_tileCache.get();
|
||||
mCacheSet* CoreController::graphicCaches() {
|
||||
if (m_cacheSet) {
|
||||
return m_cacheSet.get();
|
||||
}
|
||||
Interrupter interrupter(this);
|
||||
switch (platform()) {
|
||||
#ifdef M_CORE_GBA
|
||||
case PLATFORM_GBA: {
|
||||
GBA* gba = static_cast<GBA*>(m_threadContext.core->board);
|
||||
m_tileCache = std::make_unique<mTileCache>();
|
||||
GBAVideoTileCacheInit(m_tileCache.get());
|
||||
GBAVideoTileCacheAssociate(m_tileCache.get(), &gba->video);
|
||||
mTileCacheSetPalette(m_tileCache.get(), 0);
|
||||
m_cacheSet = std::make_unique<mCacheSet>();
|
||||
GBAVideoCacheInit(m_cacheSet.get());
|
||||
GBAVideoCacheAssociate(m_cacheSet.get(), &gba->video);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#ifdef M_CORE_GB
|
||||
case PLATFORM_GB: {
|
||||
GB* gb = static_cast<GB*>(m_threadContext.core->board);
|
||||
m_tileCache = std::make_unique<mTileCache>();
|
||||
GBVideoTileCacheInit(m_tileCache.get());
|
||||
GBVideoTileCacheAssociate(m_tileCache.get(), &gb->video);
|
||||
mTileCacheSetPalette(m_tileCache.get(), 0);
|
||||
m_cacheSet = std::make_unique<mCacheSet>();
|
||||
GBVideoCacheInit(m_cacheSet.get());
|
||||
GBVideoCacheAssociate(m_cacheSet.get(), &gb->video);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
return m_tileCache.get();
|
||||
return m_cacheSet.get();
|
||||
}
|
||||
|
||||
void CoreController::setOverride(std::unique_ptr<Override> override) {
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#include <mgba/core/core.h>
|
||||
#include <mgba/core/interface.h>
|
||||
#include <mgba/core/thread.h>
|
||||
#include <mgba/core/tile-cache.h>
|
||||
#include <mgba/core/cache-set.h>
|
||||
|
||||
#ifdef M_CORE_GB
|
||||
#include <mgba/internal/gb/sio/printer.h>
|
||||
|
@ -78,7 +78,7 @@ public:
|
|||
void clearMultiplayerController();
|
||||
MultiplayerController* multiplayerController() { return m_multiplayer; }
|
||||
|
||||
mTileCache* tileCache();
|
||||
mCacheSet* graphicCaches();
|
||||
int stateSlot() const { return m_stateSlot; }
|
||||
|
||||
void setOverride(std::unique_ptr<Override> override);
|
||||
|
@ -173,7 +173,7 @@ private:
|
|||
QByteArray* m_activeBuffer;
|
||||
QByteArray* m_completeBuffer = nullptr;
|
||||
|
||||
std::unique_ptr<mTileCache> m_tileCache;
|
||||
std::unique_ptr<mCacheSet> m_cacheSet;
|
||||
std::unique_ptr<Override> m_override;
|
||||
|
||||
QList<std::function<void()>> m_resetActions;
|
||||
|
|
|
@ -64,7 +64,7 @@ void ObjView::selectObj(int obj) {
|
|||
void ObjView::translateIndex(int index) {
|
||||
unsigned x = index % m_objInfo.width;
|
||||
unsigned y = index / m_objInfo.width;
|
||||
m_ui.tile->selectIndex(x + y * m_objInfo.stride + m_tileOffset);
|
||||
m_ui.tile->selectIndex(x + y * m_objInfo.stride + m_tileOffset + m_boundary);
|
||||
}
|
||||
|
||||
#ifdef M_CORE_GBA
|
||||
|
@ -87,19 +87,19 @@ void ObjView::updateTilesGBA(bool force) {
|
|||
unsigned bits;
|
||||
if (GBAObjAttributesAIs256Color(obj->a)) {
|
||||
m_ui.palette->setText("256-color");
|
||||
paletteSet = 1;
|
||||
paletteSet = 3;
|
||||
m_ui.tile->setBoundary(1024, 1, 3);
|
||||
m_ui.tile->setPalette(0);
|
||||
m_ui.tile->setPaletteSet(1, 1024, 1536);
|
||||
palette = 1;
|
||||
tile = tile / 2 + 1024;
|
||||
m_boundary = 1024;
|
||||
palette = 0;
|
||||
tile /= 2;
|
||||
bits = 8;
|
||||
} else {
|
||||
m_ui.palette->setText(QString::number(palette));
|
||||
paletteSet = 0;
|
||||
paletteSet = 2;
|
||||
m_ui.tile->setBoundary(2048, 0, 2);
|
||||
m_ui.tile->setPalette(palette);
|
||||
m_ui.tile->setPaletteSet(0, 2048, 3072);
|
||||
palette += 16;
|
||||
tile += 2048;
|
||||
m_boundary = 2048;
|
||||
bits = 4;
|
||||
}
|
||||
ObjInfo newInfo{
|
||||
|
@ -120,16 +120,16 @@ void ObjView::updateTilesGBA(bool force) {
|
|||
};
|
||||
m_objInfo = newInfo;
|
||||
m_tileOffset = tile;
|
||||
mTileCacheSetPalette(m_tileCache, paletteSet);
|
||||
mTileCache* tileCache = mTileCacheSetGetPointer(&m_cacheSet->tiles, paletteSet);
|
||||
|
||||
int i = 0;
|
||||
for (int y = 0; y < height / 8; ++y) {
|
||||
for (int x = 0; x < width / 8; ++x, ++i, ++tile, ++tileBase) {
|
||||
const uint16_t* data = mTileCacheGetTileIfDirty(m_tileCache, &m_tileStatus[32 * tileBase], tile, palette);
|
||||
const color_t* data = mTileCacheGetTileIfDirty(tileCache, &m_tileStatus[16 * tileBase], tile, palette);
|
||||
if (data) {
|
||||
m_ui.tiles->setTile(i, data);
|
||||
} else if (force) {
|
||||
m_ui.tiles->setTile(i, mTileCacheGetTile(m_tileCache, tile, palette));
|
||||
m_ui.tiles->setTile(i, mTileCacheGetTile(tileCache, tile, palette));
|
||||
}
|
||||
}
|
||||
tile += newInfo.stride - width / 8;
|
||||
|
@ -178,6 +178,7 @@ void ObjView::updateTilesGB(bool force) {
|
|||
const GB* gb = static_cast<const GB*>(m_controller->thread()->core->board);
|
||||
const GBObj* obj = &gb->video.oam.obj[m_objId];
|
||||
|
||||
mTileCache* tileCache = mTileCacheSetGetPointer(&m_cacheSet->tiles, 0);
|
||||
unsigned width = 8;
|
||||
unsigned height = 8;
|
||||
GBRegisterLCDC lcdc = gb->memory.io[REG_LCDC];
|
||||
|
@ -186,6 +187,7 @@ void ObjView::updateTilesGB(bool force) {
|
|||
}
|
||||
unsigned tile = obj->tile;
|
||||
m_ui.tiles->setTileCount(width * height / 64);
|
||||
m_ui.tile->setBoundary(1024, 0, 0);
|
||||
m_ui.tiles->setMinimumSize(QSize(width, height) * m_ui.magnification->value());
|
||||
m_ui.tiles->resize(QSize(width, height) * m_ui.magnification->value());
|
||||
unsigned palette = 0;
|
||||
|
@ -214,18 +216,17 @@ void ObjView::updateTilesGB(bool force) {
|
|||
}
|
||||
m_objInfo = newInfo;
|
||||
m_tileOffset = tile;
|
||||
m_boundary = 1024;
|
||||
|
||||
int i = 0;
|
||||
mTileCacheSetPalette(m_tileCache, 0);
|
||||
m_ui.tile->setPalette(palette);
|
||||
m_ui.tile->setPaletteSet(0, 512, 1024);
|
||||
for (int y = 0; y < height / 8; ++y, ++i) {
|
||||
unsigned t = tile + i;
|
||||
const uint16_t* data = mTileCacheGetTileIfDirty(m_tileCache, &m_tileStatus[16 * t], t, palette);
|
||||
const color_t* data = mTileCacheGetTileIfDirty(tileCache, &m_tileStatus[8 * t], t, palette);
|
||||
if (data) {
|
||||
m_ui.tiles->setTile(i, data);
|
||||
} else if (force) {
|
||||
m_ui.tiles->setTile(i, mTileCacheGetTile(m_tileCache, t, palette));
|
||||
m_ui.tiles->setTile(i, mTileCacheGetTile(tileCache, t, palette));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -257,21 +258,17 @@ void ObjView::exportObj() {
|
|||
}
|
||||
|
||||
CoreController::Interrupter interrupter(m_controller);
|
||||
mTileCacheSetPalette(m_tileCache, m_objInfo.paletteSet);
|
||||
png_structp png = PNGWriteOpen(vf);
|
||||
png_infop info = PNGWriteHeader8(png, m_objInfo.width * 8, m_objInfo.height * 8);
|
||||
|
||||
const uint16_t* rawPalette = mTileCacheGetPalette(m_tileCache, m_objInfo.paletteId);
|
||||
mTileCache* tileCache = mTileCacheSetGetPointer(&m_cacheSet->tiles, m_objInfo.paletteSet);
|
||||
const color_t* rawPalette = mTileCacheGetPalette(tileCache, m_objInfo.paletteId);
|
||||
unsigned colors = 1 << m_objInfo.bits;
|
||||
uint32_t palette[256];
|
||||
for (unsigned c = 0; c < colors && c < 256; ++c) {
|
||||
uint16_t color = rawPalette[c];
|
||||
palette[c] = M_R8(rawPalette[c]);
|
||||
palette[c] |= M_G8(rawPalette[c]) << 8;
|
||||
palette[c] |= M_B8(rawPalette[c]) << 16;
|
||||
if (c) {
|
||||
palette[c] |= 0xFF000000;
|
||||
}
|
||||
|
||||
palette[0] = rawPalette[0];
|
||||
for (unsigned c = 1; c < colors && c < 256; ++c) {
|
||||
palette[c] = rawPalette[c] | 0xFF000000;
|
||||
}
|
||||
PNGWritePalette(png, info, palette, colors);
|
||||
|
||||
|
@ -279,7 +276,7 @@ void ObjView::exportObj() {
|
|||
unsigned t = m_objInfo.tile;
|
||||
for (int y = 0; y < m_objInfo.height; ++y) {
|
||||
for (int x = 0; x < m_objInfo.width; ++x, ++t) {
|
||||
compositeTile(t, static_cast<void*>(buffer), m_objInfo.width * 8, x * 8, y * 8, m_objInfo.bits);
|
||||
compositeTile(static_cast<const void*>(mTileCacheGetVRAM(tileCache, t)), reinterpret_cast<color_t*>(buffer), m_objInfo.width * 8, x * 8, y * 8, m_objInfo.bits);
|
||||
}
|
||||
t += m_objInfo.stride - m_objInfo.width;
|
||||
}
|
||||
|
|
|
@ -56,6 +56,7 @@ private:
|
|||
} m_objInfo = {};
|
||||
|
||||
int m_tileOffset;
|
||||
int m_boundary;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -42,6 +42,14 @@ void Swatch::setColor(int index, uint16_t color) {
|
|||
updateFill(index);
|
||||
}
|
||||
|
||||
void Swatch::setColor(int index, uint32_t color) {
|
||||
m_colors[index].setRgb(
|
||||
(color >> 0) & 0xFF,
|
||||
(color >> 8) & 0xFF,
|
||||
(color >> 16) & 0xFF);
|
||||
updateFill(index);
|
||||
}
|
||||
|
||||
void Swatch::paintEvent(QPaintEvent* event) {
|
||||
QPainter painter(this);
|
||||
painter.drawPixmap(QPoint(), m_backing);
|
||||
|
|
|
@ -22,6 +22,7 @@ public:
|
|||
|
||||
public slots:
|
||||
void setColor(int index, uint16_t);
|
||||
void setColor(int index, uint32_t);
|
||||
|
||||
signals:
|
||||
void indexPressed(int index);
|
||||
|
|
|
@ -40,14 +40,15 @@ void TilePainter::mousePressEvent(QMouseEvent* event) {
|
|||
emit indexPressed(y * (width() / m_size) + x);
|
||||
}
|
||||
|
||||
void TilePainter::setTile(int index, const uint16_t* data) {
|
||||
void TilePainter::setTile(int index, const color_t* data) {
|
||||
QPainter painter(&m_backing);
|
||||
int w = width() / m_size;
|
||||
int x = index % w;
|
||||
int y = index / w;
|
||||
QRect r(x * m_size, y * m_size, m_size, m_size);
|
||||
QImage tile(reinterpret_cast<const uchar*>(data), 8, 8, QImage::Format_RGB555);
|
||||
painter.drawImage(r, tile.rgbSwapped());
|
||||
QImage tile(reinterpret_cast<const uchar*>(data), 8, 8, QImage::Format_ARGB32);
|
||||
tile = tile.convertToFormat(QImage::Format_RGB32).rgbSwapped();
|
||||
painter.drawImage(r, tile);
|
||||
update(r);
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
#include <QWidget>
|
||||
#include <QVector>
|
||||
|
||||
#include <mgba/core/interface.h>
|
||||
|
||||
namespace QGBA {
|
||||
|
||||
class TilePainter : public QWidget {
|
||||
|
@ -18,7 +20,7 @@ public:
|
|||
TilePainter(QWidget* parent = nullptr);
|
||||
|
||||
public slots:
|
||||
void setTile(int index, const uint16_t*);
|
||||
void setTile(int index, const color_t*);
|
||||
void setTileCount(int tiles);
|
||||
void setTileMagnification(int mag);
|
||||
|
||||
|
|
|
@ -27,38 +27,30 @@ TileView::TileView(std::shared_ptr<CoreController> controller, QWidget* parent)
|
|||
connect(m_ui.tiles, &TilePainter::indexPressed, m_ui.tile, &AssetTile::selectIndex);
|
||||
connect(m_ui.paletteId, &QAbstractSlider::valueChanged, this, &TileView::updatePalette);
|
||||
|
||||
int max = 1024;
|
||||
int boundary = 1024;
|
||||
switch (m_controller->platform()) {
|
||||
#ifdef M_CORE_GBA
|
||||
case PLATFORM_GBA:
|
||||
max = 3072;
|
||||
boundary = 2048;
|
||||
m_ui.tile->setBoundary(2048, 0, 2);
|
||||
break;
|
||||
#endif
|
||||
#ifdef M_CORE_GB
|
||||
case PLATFORM_GB:
|
||||
max = 1024;
|
||||
boundary = 512;
|
||||
m_ui.palette256->setEnabled(false);
|
||||
m_ui.tile->setBoundary(1024, 0, 0);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return;
|
||||
}
|
||||
m_ui.tile->setPaletteSet(0, boundary, max);
|
||||
|
||||
connect(m_ui.palette256, &QAbstractButton::toggled, [this](bool selected) {
|
||||
if (selected) {
|
||||
m_ui.paletteId->setValue(0);
|
||||
}
|
||||
int max = 1024;
|
||||
int boundary = 1024;
|
||||
switch (m_controller->platform()) {
|
||||
#ifdef M_CORE_GBA
|
||||
case PLATFORM_GBA:
|
||||
max = 3072 >> selected;
|
||||
boundary = 2048 >> selected;
|
||||
m_ui.tile->setBoundary(2048 >> selected, selected, selected + 2);
|
||||
break;
|
||||
#endif
|
||||
#ifdef M_CORE_GB
|
||||
|
@ -68,7 +60,6 @@ TileView::TileView(std::shared_ptr<CoreController> controller, QWidget* parent)
|
|||
default:
|
||||
break;
|
||||
}
|
||||
m_ui.tile->setPaletteSet(selected, boundary, max);
|
||||
updateTiles(true);
|
||||
});
|
||||
connect(m_ui.magnification, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), [this]() {
|
||||
|
@ -80,40 +71,42 @@ TileView::TileView(std::shared_ptr<CoreController> controller, QWidget* parent)
|
|||
void TileView::updateTilesGBA(bool force) {
|
||||
if (m_ui.palette256->isChecked()) {
|
||||
m_ui.tiles->setTileCount(1536);
|
||||
mTileCacheSetPalette(m_tileCache, 1);
|
||||
mTileCache* cache = mTileCacheSetGetPointer(&m_cacheSet->tiles, 1);
|
||||
for (int i = 0; i < 1024; ++i) {
|
||||
const uint16_t* data = mTileCacheGetTileIfDirty(m_tileCache, &m_tileStatus[32 * i], i, 0);
|
||||
const color_t* data = mTileCacheGetTileIfDirty(cache, &m_tileStatus[16 * i], i, 0);
|
||||
if (data) {
|
||||
m_ui.tiles->setTile(i, data);
|
||||
} else if (force) {
|
||||
m_ui.tiles->setTile(i, mTileCacheGetTile(m_tileCache, i, 0));
|
||||
m_ui.tiles->setTile(i, mTileCacheGetTile(cache, i, 0));
|
||||
}
|
||||
}
|
||||
cache = mTileCacheSetGetPointer(&m_cacheSet->tiles, 3);
|
||||
for (int i = 1024; i < 1536; ++i) {
|
||||
const uint16_t* data = mTileCacheGetTileIfDirty(m_tileCache, &m_tileStatus[32 * i], i, 1);
|
||||
const color_t* data = mTileCacheGetTileIfDirty(cache, &m_tileStatus[16 * i], i - 1024, 0);
|
||||
if (data) {
|
||||
m_ui.tiles->setTile(i, data);
|
||||
} else if (force) {
|
||||
m_ui.tiles->setTile(i, mTileCacheGetTile(m_tileCache, i, 1));
|
||||
m_ui.tiles->setTile(i, mTileCacheGetTile(cache, i - 1024, 0));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
mTileCache* cache = mTileCacheSetGetPointer(&m_cacheSet->tiles, 0);
|
||||
m_ui.tiles->setTileCount(3072);
|
||||
mTileCacheSetPalette(m_tileCache, 0);
|
||||
for (int i = 0; i < 2048; ++i) {
|
||||
const uint16_t* data = mTileCacheGetTileIfDirty(m_tileCache, &m_tileStatus[32 * i], i, m_paletteId);
|
||||
const color_t* data = mTileCacheGetTileIfDirty(cache, &m_tileStatus[16 * i], i, m_paletteId);
|
||||
if (data) {
|
||||
m_ui.tiles->setTile(i, data);
|
||||
} else if (force) {
|
||||
m_ui.tiles->setTile(i, mTileCacheGetTile(m_tileCache, i, m_paletteId));
|
||||
m_ui.tiles->setTile(i, mTileCacheGetTile(cache, i, m_paletteId));
|
||||
}
|
||||
}
|
||||
cache = mTileCacheSetGetPointer(&m_cacheSet->tiles, 2);
|
||||
for (int i = 2048; i < 3072; ++i) {
|
||||
const uint16_t* data = mTileCacheGetTileIfDirty(m_tileCache, &m_tileStatus[32 * i], i, m_paletteId + 16);
|
||||
const color_t* data = mTileCacheGetTileIfDirty(cache, &m_tileStatus[16 * i], i - 2048, m_paletteId);
|
||||
if (data) {
|
||||
m_ui.tiles->setTile(i, data);
|
||||
} else if (force) {
|
||||
m_ui.tiles->setTile(i, mTileCacheGetTile(m_tileCache, i, m_paletteId + 16));
|
||||
m_ui.tiles->setTile(i, mTileCacheGetTile(cache, i - 2048, m_paletteId));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -125,13 +118,13 @@ void TileView::updateTilesGB(bool force) {
|
|||
const GB* gb = static_cast<const GB*>(m_controller->thread()->core->board);
|
||||
int count = gb->model >= GB_MODEL_CGB ? 1024 : 512;
|
||||
m_ui.tiles->setTileCount(count);
|
||||
mTileCacheSetPalette(m_tileCache, 0);
|
||||
mTileCache* cache = mTileCacheSetGetPointer(&m_cacheSet->tiles, 0);
|
||||
for (int i = 0; i < count; ++i) {
|
||||
const uint16_t* data = mTileCacheGetTileIfDirty(m_tileCache, &m_tileStatus[16 * i], i, m_paletteId);
|
||||
const color_t* data = mTileCacheGetTileIfDirty(cache, &m_tileStatus[8 * i], i, m_paletteId);
|
||||
if (data) {
|
||||
m_ui.tiles->setTile(i, data);
|
||||
} else if (force) {
|
||||
m_ui.tiles->setTile(i, mTileCacheGetTile(m_tileCache, i, m_paletteId));
|
||||
m_ui.tiles->setTile(i, mTileCacheGetTile(cache, i, m_paletteId));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue