Mercurial > repos > blastem
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 { |