all repos — mgba @ 659b929f3e58d50762f3054ba634877e458cdb4c

mGBA Game Boy Advance Emulator

src/gb/renderers/cache-set.c (view raw)

  1/* Copyright (c) 2013-2017 Jeffrey Pfau
  2 *
  3 * This Source Code Form is subject to the terms of the Mozilla Public
  4 * License, v. 2.0. If a copy of the MPL was not distributed with this
  5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  6#include <mgba/internal/gb/renderers/cache-set.h>
  7
  8#include <mgba/core/cache-set.h>
  9#include <mgba/internal/gb/gb.h>
 10#include <mgba/internal/gb/io.h>
 11#include <mgba/internal/gb/video.h>
 12
 13void GBVideoCacheInit(struct mCacheSet* cache) {
 14	mCacheSetInit(cache, 2, 0, 1);
 15	mTileCacheSystemInfo sysconfig = 0;
 16	mTileCacheConfiguration config = mTileCacheConfigurationFillShouldStore(0);
 17	sysconfig = mTileCacheSystemInfoSetPaletteBPP(sysconfig, 1); // 2^(2^1) = 4 entries
 18	sysconfig = mTileCacheSystemInfoSetPaletteCount(sysconfig, 4); // 16 palettes
 19	sysconfig = mTileCacheSystemInfoSetMaxTiles(sysconfig, 1024);
 20	mTileCacheConfigureSystem(mTileCacheSetGetPointer(&cache->tiles, 0), sysconfig, 0, 0);
 21	mTileCacheConfigure(mTileCacheSetGetPointer(&cache->tiles, 0), config);
 22
 23	mMapCacheSetGetPointer(&cache->maps, 0)->tileCache = mTileCacheSetGetPointer(&cache->tiles, 0);
 24	mMapCacheSetGetPointer(&cache->maps, 1)->tileCache = mTileCacheSetGetPointer(&cache->tiles, 0);
 25}
 26
 27void GBVideoCacheAssociate(struct mCacheSet* cache, struct GBVideo* video) {
 28	mCacheSetAssignVRAM(cache, video->vram);
 29	video->renderer->cache = cache;
 30	size_t i;
 31	for (i = 0; i < 64; ++i) {
 32		mCacheSetWritePalette(cache, i, mColorFrom555(video->palette[i]));
 33	}
 34	mMapCacheSystemInfo sysconfig = mMapCacheSystemInfoSetPaletteCount(0, 0);
 35	if (video->p->model >= GB_MODEL_CGB) {
 36		sysconfig = mMapCacheSystemInfoSetPaletteCount(0, 2);
 37	}
 38	mMapCacheConfigureSystem(mMapCacheSetGetPointer(&cache->maps, 0), sysconfig);
 39	mMapCacheConfigureSystem(mMapCacheSetGetPointer(&cache->maps, 1), sysconfig);
 40
 41	GBVideoCacheWriteVideoRegister(cache, REG_LCDC, video->p->memory.io[REG_LCDC]);
 42}
 43
 44static void mapParserDMG0(struct mMapCache* cache, struct mMapCacheEntry* entry, void* vram) {
 45	UNUSED(cache);
 46	int map = *(uint8_t*) vram;
 47	entry->tileId = map;
 48	entry->flags = mMapCacheEntryFlagsClearHMirror(entry->flags);
 49	entry->flags = mMapCacheEntryFlagsClearVMirror(entry->flags);
 50	entry->flags = mMapCacheEntryFlagsSetPaletteId(entry->flags, 0);
 51}
 52
 53static void mapParserDMG1(struct mMapCache* cache, struct mMapCacheEntry* entry, void* vram) {
 54	UNUSED(cache);
 55	int map = *(int8_t*) vram;
 56	entry->tileId = map + 128;
 57	entry->flags = mMapCacheEntryFlagsClearHMirror(entry->flags);
 58	entry->flags = mMapCacheEntryFlagsClearVMirror(entry->flags);
 59	entry->flags = mMapCacheEntryFlagsSetPaletteId(entry->flags, 0);
 60}
 61
 62static void mapParserCGB0(struct mMapCache* cache, struct mMapCacheEntry* entry, void* vram) {
 63	UNUSED(cache);
 64	int map = *(uint8_t*) vram;
 65	uint8_t attr = ((uint8_t*) vram)[0x2000];
 66	entry->tileId = map + GBObjAttributesGetBank(attr) * 512;
 67	entry->flags = mMapCacheEntryFlagsSetHMirror(entry->flags, GBObjAttributesGetXFlip(attr));
 68	entry->flags = mMapCacheEntryFlagsSetVMirror(entry->flags, GBObjAttributesGetYFlip(attr));
 69	entry->flags = mMapCacheEntryFlagsSetPaletteId(entry->flags, GBObjAttributesGetCGBPalette(attr));
 70}
 71
 72static void mapParserCGB1(struct mMapCache* cache, struct mMapCacheEntry* entry, void* vram) {
 73	UNUSED(cache);
 74	int map = *(int8_t*) vram;
 75	uint8_t attr = ((uint8_t*) vram)[0x2000];
 76	entry->tileId = map + 128 + GBObjAttributesGetBank(attr) * 512;
 77	entry->flags = mMapCacheEntryFlagsSetHMirror(entry->flags, GBObjAttributesGetXFlip(attr));
 78	entry->flags = mMapCacheEntryFlagsSetVMirror(entry->flags, GBObjAttributesGetYFlip(attr));
 79	entry->flags = mMapCacheEntryFlagsSetPaletteId(entry->flags, GBObjAttributesGetCGBPalette(attr));
 80}
 81
 82void GBVideoCacheWriteVideoRegister(struct mCacheSet* cache, uint16_t address, uint8_t value) {
 83	if (address != REG_LCDC) {
 84		return;
 85	}
 86	struct mMapCache* map = mMapCacheSetGetPointer(&cache->maps, 0);
 87	struct mMapCache* window = mMapCacheSetGetPointer(&cache->maps, 1);
 88
 89	mMapCacheSystemInfo sysconfig = mMapCacheSystemInfoIsPaletteCount(map->sysConfig);
 90	int tileStart = 0;
 91	int mapStart = GB_BASE_MAP;
 92	int windowStart = GB_BASE_MAP;
 93	if (GBRegisterLCDCIsTileMap(value)) {
 94		mapStart += GB_SIZE_MAP;
 95	}
 96	if (GBRegisterLCDCIsWindowTileMap(value)) {
 97		windowStart += GB_SIZE_MAP;
 98	}
 99	if (GBRegisterLCDCIsTileData(value)) {
100		if (!sysconfig) {
101			map->mapParser = mapParserDMG0;
102			window->mapParser = mapParserDMG0;
103		} else {
104			map->mapParser = mapParserCGB0;
105			window->mapParser = mapParserCGB0;
106		}
107	} else {
108		if (!sysconfig) {
109			map->mapParser = mapParserDMG1;
110			window->mapParser = mapParserDMG1;
111		} else {
112			map->mapParser = mapParserCGB1;
113			window->mapParser = mapParserCGB1;
114		}
115		tileStart = 0x80;
116	}
117	map->tileStart = tileStart;
118	window->tileStart = tileStart;
119	sysconfig = mMapCacheSystemInfoSetMacroTileSize(sysconfig, 5);
120	sysconfig = mMapCacheSystemInfoSetPaletteBPP(sysconfig, 1);
121	sysconfig = mMapCacheSystemInfoSetMapAlign(sysconfig, 0);
122	sysconfig = mMapCacheSystemInfoSetTilesHigh(sysconfig, 5);
123	sysconfig = mMapCacheSystemInfoSetTilesWide(sysconfig, 5);
124	mMapCacheConfigureSystem(map, sysconfig);
125	mMapCacheConfigureSystem(window, sysconfig);
126	mMapCacheConfigureMap(map, mapStart);
127	mMapCacheConfigureMap(window, windowStart);
128}