all repos — mgba @ fbe375fab992cb4bb2fbc005ed26bc488ccb3389

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	mTileCacheConfiguration config = 0;
 16	config = mTileCacheSystemInfoSetPaletteBPP(config, 1); // 2^(2^1) = 4 entries
 17	config = mTileCacheSystemInfoSetPaletteCount(config, 4); // 16 palettes
 18	config = mTileCacheSystemInfoSetMaxTiles(config, 1024);
 19	mTileCacheConfigureSystem(mTileCacheSetGetPointer(&cache->tiles, 0), config, 0, 0);
 20
 21	mMapCacheSetGetPointer(&cache->maps, 0)->tileCache = mTileCacheSetGetPointer(&cache->tiles, 0);
 22	mMapCacheSetGetPointer(&cache->maps, 1)->tileCache = mTileCacheSetGetPointer(&cache->tiles, 0);
 23}
 24
 25void GBVideoCacheAssociate(struct mCacheSet* cache, struct GBVideo* video) {
 26	mCacheSetAssignVRAM(cache, video->vram);
 27	video->renderer->cache = cache;
 28	size_t i;
 29	for (i = 0; i < 64; ++i) {
 30		mCacheSetWritePalette(cache, i, mColorFrom555(video->palette[i]));
 31	}
 32	mMapCacheSystemInfo sysconfig = mMapCacheSystemInfoSetPaletteCount(0, 0);
 33	if (video->p->model >= GB_MODEL_CGB) {
 34		sysconfig = mMapCacheSystemInfoSetPaletteCount(0, 2);
 35	}
 36	mMapCacheConfigureSystem(mMapCacheSetGetPointer(&cache->maps, 0), sysconfig);
 37	mMapCacheConfigureSystem(mMapCacheSetGetPointer(&cache->maps, 1), sysconfig);
 38
 39	GBVideoCacheWriteVideoRegister(cache, REG_LCDC, video->p->memory.io[REG_LCDC]);
 40}
 41
 42static void mapParserDMG0(struct mMapCache* cache, struct mMapCacheEntry* entry, void* vram) {
 43	UNUSED(cache);
 44	int map = *(uint8_t*) vram;
 45	entry->tileId = map;
 46	entry->flags = mMapCacheEntryFlagsClearHMirror(entry->flags);
 47	entry->flags = mMapCacheEntryFlagsClearVMirror(entry->flags);
 48	entry->flags = mMapCacheEntryFlagsSetPaletteId(entry->flags, 0);
 49}
 50
 51static void mapParserDMG1(struct mMapCache* cache, struct mMapCacheEntry* entry, void* vram) {
 52	UNUSED(cache);
 53	int map = *(int8_t*) vram;
 54	entry->tileId = map + 128;
 55	entry->flags = mMapCacheEntryFlagsClearHMirror(entry->flags);
 56	entry->flags = mMapCacheEntryFlagsClearVMirror(entry->flags);
 57	entry->flags = mMapCacheEntryFlagsSetPaletteId(entry->flags, 0);
 58}
 59
 60static void mapParserCGB0(struct mMapCache* cache, struct mMapCacheEntry* entry, void* vram) {
 61	UNUSED(cache);
 62	int map = *(uint8_t*) vram;
 63	uint8_t attr = ((uint8_t*) vram)[0x2000];
 64	entry->tileId = map + GBObjAttributesGetBank(attr) * 512;
 65	entry->flags = mMapCacheEntryFlagsSetHMirror(entry->flags, GBObjAttributesGetXFlip(attr));
 66	entry->flags = mMapCacheEntryFlagsSetVMirror(entry->flags, GBObjAttributesGetYFlip(attr));
 67	entry->flags = mMapCacheEntryFlagsSetPaletteId(entry->flags, GBObjAttributesGetCGBPalette(attr));
 68}
 69
 70static void mapParserCGB1(struct mMapCache* cache, struct mMapCacheEntry* entry, void* vram) {
 71	UNUSED(cache);
 72	int map = *(int8_t*) vram;
 73	uint8_t attr = ((uint8_t*) vram)[0x2000];
 74	entry->tileId = map + 128 + GBObjAttributesGetBank(attr) * 512;
 75	entry->flags = mMapCacheEntryFlagsSetHMirror(entry->flags, GBObjAttributesGetXFlip(attr));
 76	entry->flags = mMapCacheEntryFlagsSetVMirror(entry->flags, GBObjAttributesGetYFlip(attr));
 77	entry->flags = mMapCacheEntryFlagsSetPaletteId(entry->flags, GBObjAttributesGetCGBPalette(attr));
 78}
 79
 80void GBVideoCacheWriteVideoRegister(struct mCacheSet* cache, uint16_t address, uint8_t value) {
 81	if (address != REG_LCDC) {
 82		return;
 83	}
 84	struct mMapCache* map = mMapCacheSetGetPointer(&cache->maps, 0);
 85	struct mMapCache* window = mMapCacheSetGetPointer(&cache->maps, 1);
 86
 87	mMapCacheSystemInfo sysconfig = mMapCacheSystemInfoIsPaletteCount(map->sysConfig);
 88	int tileStart = 0;
 89	int mapStart = GB_BASE_MAP;
 90	int windowStart = GB_BASE_MAP;
 91	if (GBRegisterLCDCIsTileMap(value)) {
 92		mapStart += GB_SIZE_MAP;
 93	}
 94	if (GBRegisterLCDCIsWindowTileMap(value)) {
 95		windowStart += GB_SIZE_MAP;
 96	}
 97	if (GBRegisterLCDCIsTileData(value)) {
 98		if (!sysconfig) {
 99			map->mapParser = mapParserDMG0;
100			window->mapParser = mapParserDMG0;
101		} else {
102			map->mapParser = mapParserCGB0;
103			window->mapParser = mapParserCGB0;
104		}
105	} else {
106		if (!sysconfig) {
107			map->mapParser = mapParserDMG1;
108			window->mapParser = mapParserDMG1;
109		} else {
110			map->mapParser = mapParserCGB1;
111			window->mapParser = mapParserCGB1;
112		}
113		tileStart = 0x80;
114	}
115	map->tileStart = tileStart;
116	window->tileStart = tileStart;
117	sysconfig = mMapCacheSystemInfoSetMacroTileSize(sysconfig, 5);
118	sysconfig = mMapCacheSystemInfoSetPaletteBPP(sysconfig, 1);
119	sysconfig = mMapCacheSystemInfoSetMapAlign(sysconfig, 0);
120	sysconfig = mMapCacheSystemInfoSetTilesHigh(sysconfig, 5);
121	sysconfig = mMapCacheSystemInfoSetTilesWide(sysconfig, 5);
122	mMapCacheConfigureSystem(map, sysconfig);
123	mMapCacheConfigureSystem(window, sysconfig);
124	mMapCacheConfigureMap(map, mapStart);
125	mMapCacheConfigureMap(window, windowStart);
126}