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}