Mercurial > repos > blastem
comparison cd_graphics.c @ 2271:3ef80963c2a7
Fix stamp address mask and add WIP CD graphics debug view
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Thu, 29 Dec 2022 15:47:19 -0800 |
parents | da326c32ad8f |
children | a1afe26a8ef0 |
comparison
equal
deleted
inserted
replaced
2270:827ab6dd534a | 2271:3ef80963c2a7 |
---|---|
1 #include "cd_graphics.h" | 1 #include "cd_graphics.h" |
2 #include "backend.h" | 2 #include "backend.h" |
3 #include "render.h" | |
3 | 4 |
4 void cd_graphics_init(segacd_context *cd) | 5 void cd_graphics_init(segacd_context *cd) |
5 { | 6 { |
6 cd->graphics_int_cycle = CYCLE_NEVER; | 7 cd->graphics_int_cycle = CYCLE_NEVER; |
7 } | 8 } |
20 uint16_t stamp_num_mask; | 21 uint16_t stamp_num_mask; |
21 if (cd->gate_array[GA_STAMP_SIZE] & BIT_STS) { | 22 if (cd->gate_array[GA_STAMP_SIZE] & BIT_STS) { |
22 //32x32 stamps | 23 //32x32 stamps |
23 stamp_shift = 5; | 24 stamp_shift = 5; |
24 pixel_mask = 0x1F; | 25 pixel_mask = 0x1F; |
25 stamp_num_mask = 0x3FC; | 26 stamp_num_mask = 0x7FC; |
26 } else { | 27 } else { |
27 //16x16 stamps | 28 //16x16 stamps |
28 stamp_shift = 4; | 29 stamp_shift = 4; |
29 pixel_mask = 0xF; | 30 pixel_mask = 0xF; |
30 stamp_num_mask = 0x3FF; | 31 stamp_num_mask = 0x7FF; |
31 } | 32 } |
32 uint16_t stamp_x = x >> stamp_shift; | 33 uint16_t stamp_x = x >> stamp_shift; |
33 uint16_t stamp_y = y >> stamp_shift; | 34 uint16_t stamp_y = y >> stamp_shift; |
34 uint16_t max, base_mask; | 35 uint16_t max, base_mask; |
35 uint32_t row_shift; | 36 uint32_t row_shift; |
247 CHECK_ONLY; | 248 CHECK_ONLY; |
248 } | 249 } |
249 } | 250 } |
250 } | 251 } |
251 | 252 |
253 void scd_toggle_graphics_debug(segacd_context *cd) | |
254 { | |
255 if (cd->graphics_debug_window) { | |
256 render_destroy_window(cd->graphics_debug_window); | |
257 cd->graphics_debug_window = 0; | |
258 } else { | |
259 cd->graphics_debug_window = render_create_window("CD ASIC", 1024, 1024, NULL); | |
260 } | |
261 } | |
262 | |
263 static void render_graphics_debug(segacd_context *cd) | |
264 { | |
265 int pitch; | |
266 uint32_t *fb = render_get_framebuffer(cd->graphics_debug_window, &pitch); | |
267 uint32_t pixels = (cd->gate_array[GA_STAMP_SIZE] & BIT_SMS) ? 4096 : 256; | |
268 uint32_t stamp_size = (cd->gate_array[GA_STAMP_SIZE] & BIT_STS) ? 32 : 16; | |
269 uint32_t num_stamps = pixels / stamp_size; | |
270 //TODO: fix mask based on SMS and STS | |
271 uint32_t address = (cd->gate_array[GA_STAMP_MAP_BASE] & 0xFFE0) << 1; | |
272 genesis_context *gen = cd->genesis; | |
273 for (uint32_t stamp_y = 0; stamp_y < num_stamps; stamp_y++) | |
274 { | |
275 uint32_t start_y = stamp_y * stamp_size; | |
276 for (uint32_t stamp_x = 0; stamp_x < num_stamps; stamp_x++) | |
277 { | |
278 uint16_t entry = cd->word_ram[address++]; | |
279 uint32_t tile_address = (entry & 0x7FF) << 6; | |
280 //TODO: flip and rotation | |
281 uint32_t start_x = stamp_x * stamp_size; | |
282 if (start_x < 1024 && start_y < 1024) { | |
283 for (uint32_t tile_x = start_x; tile_x < start_x + stamp_size; tile_x+=8) | |
284 { | |
285 for (uint32_t y = start_y; y < start_y + stamp_size; y++) | |
286 { | |
287 uint32_t *line = fb + y * pitch / sizeof(uint32_t); | |
288 for (uint32_t x = tile_x; x < tile_x + 8; x += 4) | |
289 { | |
290 | |
291 uint16_t word = cd->word_ram[tile_address++]; | |
292 uint16_t pixels[4] = { | |
293 word >> 12, | |
294 word >> 8 & 0xF, | |
295 word >> 4 & 0xF, | |
296 word & 0xF | |
297 }; | |
298 for (uint32_t i = 0; i < 4; i++) | |
299 { | |
300 line[x + i] = gen->vdp->colors[pixels[i]]; | |
301 } | |
302 } | |
303 } | |
304 } | |
305 } | |
306 } | |
307 } | |
308 render_framebuffer_updated(cd->graphics_debug_window, 1024); | |
309 } | |
310 | |
252 void cd_graphics_run(segacd_context *cd, uint32_t cycle) | 311 void cd_graphics_run(segacd_context *cd, uint32_t cycle) |
253 { | 312 { |
254 while (cd->graphics_cycle < cycle) | 313 while (cd->graphics_cycle < cycle) |
255 { | 314 { |
256 if (cd->gate_array[GA_STAMP_SIZE] & BIT_GRON) { | 315 if (cd->gate_array[GA_STAMP_SIZE] & BIT_GRON) { |
261 { | 320 { |
262 } | 321 } |
263 if (cd->graphics_cycle >= cd->graphics_int_cycle) { | 322 if (cd->graphics_cycle >= cd->graphics_int_cycle) { |
264 printf("graphics end %u\n", cd->graphics_cycle); | 323 printf("graphics end %u\n", cd->graphics_cycle); |
265 cd->gate_array[GA_STAMP_SIZE] &= ~BIT_GRON; | 324 cd->gate_array[GA_STAMP_SIZE] &= ~BIT_GRON; |
325 | |
326 if (cd->graphics_debug_window) { | |
327 render_graphics_debug(cd); | |
328 } | |
266 break; | 329 break; |
267 } | 330 } |
268 } else { | 331 } else { |
269 cd->graphics_cycle = cycle; | 332 cd->graphics_cycle = cycle; |
270 } | 333 } |