src/gba/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/gba/renderers/cache-set.h>
7
8#include <mgba/core/cache-set.h>
9#include <mgba/internal/gba/gba.h>
10#include <mgba/internal/gba/io.h>
11#include <mgba/internal/gba/video.h>
12
13void GBAVideoCacheInit(struct mCacheSet* cache) {
14 mCacheSetInit(cache, 4, 4);
15 mTileCacheSystemInfo sysconfig = 0;
16 mTileCacheConfiguration config = mTileCacheConfigurationFillShouldStore(0);
17 sysconfig = mTileCacheSystemInfoSetPaletteBPP(sysconfig, 2); // 2^(2^2) = 16 entries
18 sysconfig = mTileCacheSystemInfoSetPaletteCount(sysconfig, 4); // 16 palettes
19 sysconfig = mTileCacheSystemInfoSetMaxTiles(sysconfig, 2048);
20 mTileCacheInit(mTileCacheSetGetPointer(&cache->tiles, 0));
21 mTileCacheConfigure(mTileCacheSetGetPointer(&cache->tiles, 0), config);
22 mTileCacheConfigureSystem(mTileCacheSetGetPointer(&cache->tiles, 0), sysconfig, 0, 0);
23 sysconfig = mTileCacheSystemInfoSetMaxTiles(sysconfig, 1024);
24 mTileCacheInit(mTileCacheSetGetPointer(&cache->tiles, 2));
25 mTileCacheConfigure(mTileCacheSetGetPointer(&cache->tiles, 2), config);
26 mTileCacheConfigureSystem(mTileCacheSetGetPointer(&cache->tiles, 2), sysconfig, 0x10000, 0x100);
27
28 sysconfig = mTileCacheSystemInfoSetPaletteBPP(sysconfig, 3); // 2^(2^3) = 256 entries
29 sysconfig = mTileCacheSystemInfoSetPaletteCount(sysconfig, 0); // 1 palettes
30 sysconfig = mTileCacheSystemInfoSetMaxTiles(sysconfig, 2048);
31 mTileCacheInit(mTileCacheSetGetPointer(&cache->tiles, 1));
32 mTileCacheConfigure(mTileCacheSetGetPointer(&cache->tiles, 1), config);
33 mTileCacheConfigureSystem(mTileCacheSetGetPointer(&cache->tiles, 1), sysconfig, 0, 0);
34 sysconfig = mTileCacheSystemInfoSetMaxTiles(sysconfig, 1024);
35 mTileCacheInit(mTileCacheSetGetPointer(&cache->tiles, 3));
36 mTileCacheConfigure(mTileCacheSetGetPointer(&cache->tiles, 3), config);
37 mTileCacheConfigureSystem(mTileCacheSetGetPointer(&cache->tiles, 3), sysconfig, 0x10000, 0x100);
38
39 mMapCacheInit(mMapCacheSetGetPointer(&cache->maps, 0));
40 mMapCacheInit(mMapCacheSetGetPointer(&cache->maps, 1));
41 mMapCacheInit(mMapCacheSetGetPointer(&cache->maps, 2));
42 mMapCacheInit(mMapCacheSetGetPointer(&cache->maps, 3));
43}
44
45void GBAVideoCacheAssociate(struct mCacheSet* cache, struct GBAVideo* video) {
46 mCacheSetAssignVRAM(cache, video->vram);
47 video->renderer->cache = cache;
48 size_t i;
49 for (i = 0; i < SIZE_PALETTE_RAM / 2; ++i) {
50 mCacheSetWritePalette(cache, i, mColorFrom555(video->palette[i]));
51 }
52}
53
54static void mapParser0(struct mMapCache* cache, struct mMapCacheEntry* entry, void* vram) {
55 UNUSED(cache);
56 uint16_t map = *(uint16_t*) vram;
57 entry->tileId = GBA_TEXT_MAP_TILE(map);
58 entry->flags = mMapCacheEntryFlagsSetHMirror(entry->flags, GBA_TEXT_MAP_HFLIP(map));
59 entry->flags = mMapCacheEntryFlagsSetHMirror(entry->flags, GBA_TEXT_MAP_VFLIP(map));
60 entry->flags = mMapCacheEntryFlagsSetPaletteId(entry->flags, GBA_TEXT_MAP_PALETTE(map));
61}
62
63static void mapParser2(struct mMapCache* cache, struct mMapCacheEntry* entry, void* vram) {
64 UNUSED(cache);
65 entry->tileId = *(uint8_t*) vram;
66 entry->flags = mMapCacheEntryFlagsClearHMirror(entry->flags);
67 entry->flags = mMapCacheEntryFlagsClearHMirror(entry->flags);
68 entry->flags = mMapCacheEntryFlagsClearPaletteId(entry->flags);
69}
70
71static void GBAVideoCacheWriteDISPCNT(struct mCacheSet* cache, uint16_t value) {
72 switch (GBARegisterDISPCNTGetMode(value)) {
73 case 0:
74 default:
75 mMapCacheSetGetPointer(&cache->maps, 0)->mapParser = mapParser0;
76 mMapCacheSetGetPointer(&cache->maps, 1)->mapParser = mapParser0;
77 mMapCacheSetGetPointer(&cache->maps, 2)->mapParser = mapParser0;
78 mMapCacheSetGetPointer(&cache->maps, 3)->mapParser = mapParser0;
79
80 mMapCacheSetGetPointer(&cache->maps, 0)->tileCache = mTileCacheSetGetPointer(&cache->tiles, 0);
81 mMapCacheSetGetPointer(&cache->maps, 1)->tileCache = mTileCacheSetGetPointer(&cache->tiles, 0);
82 mMapCacheSetGetPointer(&cache->maps, 2)->tileCache = mTileCacheSetGetPointer(&cache->tiles, 0);
83 mMapCacheSetGetPointer(&cache->maps, 3)->tileCache = mTileCacheSetGetPointer(&cache->tiles, 0);
84 break;
85 case 1:
86 case 2:
87 mMapCacheSetGetPointer(&cache->maps, 0)->mapParser = mapParser0;
88 mMapCacheSetGetPointer(&cache->maps, 1)->mapParser = mapParser0;
89 mMapCacheSetGetPointer(&cache->maps, 2)->mapParser = mapParser2;
90 mMapCacheSetGetPointer(&cache->maps, 3)->mapParser = mapParser2;
91
92 mMapCacheSetGetPointer(&cache->maps, 0)->tileCache = mTileCacheSetGetPointer(&cache->tiles, 1);
93 mMapCacheSetGetPointer(&cache->maps, 1)->tileCache = mTileCacheSetGetPointer(&cache->tiles, 1);
94 mMapCacheSetGetPointer(&cache->maps, 2)->tileCache = mTileCacheSetGetPointer(&cache->tiles, 1);
95 mMapCacheSetGetPointer(&cache->maps, 3)->tileCache = mTileCacheSetGetPointer(&cache->tiles, 1);
96 break;
97 }
98}
99
100static void GBAVideoCacheWriteBGCNT(struct mCacheSet* cache, size_t bg, uint16_t value) {
101 struct mMapCache* map = mMapCacheSetGetPointer(&cache->maps, bg);
102
103 int tileStart = GBARegisterBGCNTGetCharBase(value) * 128;
104 bool p = GBARegisterBGCNTGet256Color(value);
105 mMapCacheConfigureMap(map, GBARegisterBGCNTGetScreenBase(value) << 11);
106 int size = GBARegisterBGCNTGetSize(value);
107 int tilesWide = 0;
108 int tilesHigh = 0;
109 mMapCacheSystemInfo sysconfig = 0;
110 if (map->mapParser == mapParser0) {
111 sysconfig = mMapCacheSystemInfoSetPaletteBPP(sysconfig, 2 + p);
112 sysconfig = mMapCacheSystemInfoSetPaletteCount(sysconfig, 4 * !p);
113 sysconfig = mMapCacheSystemInfoSetMaxTiles(sysconfig, 512);
114 sysconfig = mMapCacheSystemInfoSetMapAlign(sysconfig, 1);
115 tilesWide = 5;
116 tilesHigh = 5;
117 if (size & 1) {
118 ++tilesWide;
119 }
120 if (size & 2) {
121 ++tilesHigh;
122 }
123 map->tileStart = tileStart * 2;
124 } else if (map->mapParser == mapParser2) {
125 sysconfig = mMapCacheSystemInfoSetPaletteBPP(sysconfig, 3);
126 sysconfig = mMapCacheSystemInfoSetPaletteCount(sysconfig, 0);
127 sysconfig = mMapCacheSystemInfoSetMaxTiles(sysconfig, 256);
128 sysconfig = mMapCacheSystemInfoSetMapAlign(sysconfig, 0);
129
130 tilesHigh = 4 + size;
131 tilesWide = 4 + size;
132 map->tileStart = tileStart;
133 }
134 sysconfig = mMapCacheSystemInfoSetTilesHigh(sysconfig, tilesHigh);
135 sysconfig = mMapCacheSystemInfoSetTilesWide(sysconfig, tilesWide);
136 mMapCacheConfigureSystem(map, sysconfig);
137}
138
139void GBAVideoCacheWriteVideoRegister(struct mCacheSet* cache, uint32_t address, uint16_t value) {
140 switch (address) {
141 case REG_DISPCNT:
142 GBAVideoCacheWriteDISPCNT(cache, value);
143 break;
144 case REG_BG0CNT:
145 GBAVideoCacheWriteBGCNT(cache, 0, value);
146 break;
147 case REG_BG1CNT:
148 GBAVideoCacheWriteBGCNT(cache, 1, value);
149 break;
150 case REG_BG2CNT:
151 GBAVideoCacheWriteBGCNT(cache, 2, value);
152 break;
153 case REG_BG3CNT:
154 GBAVideoCacheWriteBGCNT(cache, 3, value);
155 break;
156
157 }
158}