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}