comparison vdp.c @ 2236:c149c929361c

Fix color bug when switching between Game Gear and other Sega systems
author Michael Pavone <pavone@retrodev.com>
date Tue, 13 Sep 2022 20:18:03 -0700
parents 3888c7ed4e36
children 48f718126099 0d1d5dccdd28
comparison
equal deleted inserted replaced
2235:93918a6a8ab7 2236:c149c929361c
58 INACTIVE = 0, 58 INACTIVE = 0,
59 PREPARING, //used for line 0x1FF 59 PREPARING, //used for line 0x1FF
60 ACTIVE 60 ACTIVE
61 }; 61 };
62 62
63 static int32_t color_map[1 << 12];
64 static uint16_t mode4_address_map[0x4000]; 63 static uint16_t mode4_address_map[0x4000];
65 static uint32_t planar_to_chunky[256]; 64 static uint32_t planar_to_chunky[256];
66 static uint8_t levels[] = {0, 27, 49, 71, 87, 103, 119, 130, 146, 157, 174, 190, 206, 228, 255}; 65 static uint8_t levels[] = {0, 27, 49, 71, 87, 103, 119, 130, 146, 157, 174, 190, 206, 228, 255};
67 66
68 static uint8_t debug_base[][3] = { 67 static uint8_t debug_base[][3] = {
143 } 142 }
144 context->border_top = calc_crop(top_crop, border_top); 143 context->border_top = calc_crop(top_crop, border_top);
145 context->top_offset = border_top - context->border_top; 144 context->top_offset = border_top - context->border_top;
146 } 145 }
147 146
148 static uint8_t color_map_init_done; 147 static uint8_t static_table_init_done;
149 148
150 vdp_context *init_vdp_context(uint8_t region_pal, uint8_t has_max_vsram, uint8_t type) 149 vdp_context *init_vdp_context(uint8_t region_pal, uint8_t has_max_vsram, uint8_t type)
151 { 150 {
152 vdp_context *context = calloc(1, sizeof(vdp_context) + VRAM_SIZE); 151 vdp_context *context = calloc(1, sizeof(vdp_context) + VRAM_SIZE);
153 if (headless) { 152 if (headless) {
161 context->fifo_write = 0; 160 context->fifo_write = 0;
162 context->fifo_read = -1; 161 context->fifo_read = -1;
163 context->regs[REG_HINT] = context->hint_counter = 0xFF; 162 context->regs[REG_HINT] = context->hint_counter = 0xFF;
164 context->vsram_size = has_max_vsram ? MAX_VSRAM_SIZE : MIN_VSRAM_SIZE; 163 context->vsram_size = has_max_vsram ? MAX_VSRAM_SIZE : MIN_VSRAM_SIZE;
165 context->type = type; 164 context->type = type;
166 165 uint8_t b,g,r;
167 if (!color_map_init_done) { 166 for (uint16_t color = 0; color < (1 << 12); color++) {
168 uint8_t b,g,r; 167 if (type == VDP_GAMEGEAR) {
169 for (uint16_t color = 0; color < (1 << 12); color++) { 168 b = (color >> 8 & 0xF) * 0x11;
170 if (type == VDP_GAMEGEAR) { 169 g = (color >> 4 & 0xF) * 0x11;
171 b = (color >> 8 & 0xF) * 0x11; 170 r = (color & 0xF) * 0x11;
172 g = (color >> 4 & 0xF) * 0x11; 171 }else if (color & FBUF_SHADOW) {
173 r = (color & 0xF) * 0x11; 172 b = levels[(color >> 9) & 0x7];
174 }else if (color & FBUF_SHADOW) { 173 g = levels[(color >> 5) & 0x7];
175 b = levels[(color >> 9) & 0x7]; 174 r = levels[(color >> 1) & 0x7];
176 g = levels[(color >> 5) & 0x7]; 175 } else if(color & FBUF_HILIGHT) {
177 r = levels[(color >> 1) & 0x7]; 176 b = levels[((color >> 9) & 0x7) + 7];
178 } else if(color & FBUF_HILIGHT) { 177 g = levels[((color >> 5) & 0x7) + 7];
179 b = levels[((color >> 9) & 0x7) + 7]; 178 r = levels[((color >> 1) & 0x7) + 7];
180 g = levels[((color >> 5) & 0x7) + 7]; 179 } else if(color & FBUF_MODE4) {
181 r = levels[((color >> 1) & 0x7) + 7]; 180 //TODO: Mode 4 has a separate DAC tap so this isn't quite correct
182 } else if(color & FBUF_MODE4) { 181 b = levels[(color >> 4 & 0xC) | (color >> 6 & 0x2)];
183 //TODO: Mode 4 has a separate DAC tap so this isn't quite correct 182 g = levels[(color >> 2 & 0x8) | (color >> 1 & 0x4) | (color >> 4 & 0x2)];
184 b = levels[(color >> 4 & 0xC) | (color >> 6 & 0x2)]; 183 r = levels[(color << 1 & 0xC) | (color >> 1 & 0x2)];
185 g = levels[(color >> 2 & 0x8) | (color >> 1 & 0x4) | (color >> 4 & 0x2)]; 184 } else {
186 r = levels[(color << 1 & 0xC) | (color >> 1 & 0x2)]; 185 b = levels[(color >> 8) & 0xE];
187 } else { 186 g = levels[(color >> 4) & 0xE];
188 b = levels[(color >> 8) & 0xE]; 187 r = levels[color & 0xE];
189 g = levels[(color >> 4) & 0xE]; 188 }
190 r = levels[color & 0xE]; 189 context->color_map[color] = render_map_color(r, g, b);
191 } 190 }
192 color_map[color] = render_map_color(r, g, b); 191
193 } 192 if (!static_table_init_done) {
193
194 for (uint16_t mode4_addr = 0; mode4_addr < 0x4000; mode4_addr++) 194 for (uint16_t mode4_addr = 0; mode4_addr < 0x4000; mode4_addr++)
195 { 195 {
196 uint16_t mode5_addr = mode4_addr & 0x3DFD; 196 uint16_t mode5_addr = mode4_addr & 0x3DFD;
197 mode5_addr |= mode4_addr << 8 & 0x200; 197 mode5_addr |= mode4_addr << 8 & 0x200;
198 mode5_addr |= mode4_addr >> 8 & 2; 198 mode5_addr |= mode4_addr >> 8 & 2;
206 chunky = chunky << 4; 206 chunky = chunky << 4;
207 chunky |= planar >> bit & 1; 207 chunky |= planar >> bit & 1;
208 } 208 }
209 planar_to_chunky[planar] = chunky; 209 planar_to_chunky[planar] = chunky;
210 } 210 }
211 color_map_init_done = 1; 211 static_table_init_done = 1;
212 } 212 }
213 for (uint8_t color = 0; color < (1 << (3 + 1 + 1 + 1)); color++) 213 for (uint8_t color = 0; color < (1 << (3 + 1 + 1 + 1)); color++)
214 { 214 {
215 uint8_t src = color & DBG_SRC_MASK; 215 uint8_t src = color & DBG_SRC_MASK;
216 if (src > DBG_SRC_S) { 216 if (src > DBG_SRC_S) {
838 //rough estimate of slot number at which border display starts 838 //rough estimate of slot number at which border display starts
839 #define BG_START_SLOT 6 839 #define BG_START_SLOT 6
840 840
841 static void update_color_map(vdp_context *context, uint16_t index, uint16_t value) 841 static void update_color_map(vdp_context *context, uint16_t index, uint16_t value)
842 { 842 {
843 context->colors[index] = color_map[value & CRAM_BITS]; 843 context->colors[index] = context->color_map[value & CRAM_BITS];
844 context->colors[index + SHADOW_OFFSET] = color_map[(value & CRAM_BITS) | FBUF_SHADOW]; 844 context->colors[index + SHADOW_OFFSET] = context->color_map[(value & CRAM_BITS) | FBUF_SHADOW];
845 context->colors[index + HIGHLIGHT_OFFSET] = color_map[(value & CRAM_BITS) | FBUF_HILIGHT]; 845 context->colors[index + HIGHLIGHT_OFFSET] = context->color_map[(value & CRAM_BITS) | FBUF_HILIGHT];
846 if (context->type == VDP_GAMEGEAR) { 846 if (context->type == VDP_GAMEGEAR) {
847 context->colors[index + MODE4_OFFSET] = color_map[value & 0xFFF]; 847 context->colors[index + MODE4_OFFSET] = context->color_map[value & 0xFFF];
848 } else { 848 } else {
849 context->colors[index + MODE4_OFFSET] = color_map[(value & CRAM_BITS) | FBUF_MODE4]; 849 context->colors[index + MODE4_OFFSET] = context->color_map[(value & CRAM_BITS) | FBUF_MODE4];
850 } 850 }
851 } 851 }
852 852
853 void write_cram_internal(vdp_context * context, uint16_t addr, uint16_t value) 853 void write_cram_internal(vdp_context * context, uint16_t addr, uint16_t value)
854 { 854 {