all repos — mgba @ 229d138dacd0df43d14a498ad190200bde17df9c

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