comparison vdp.c @ 21:72ce60cb1711

Sprites somewhat less broken
author Mike Pavone <pavone@retrodev.com>
date Sat, 08 Dec 2012 11:12:17 -0800
parents f664eeb55cb4
children f090a98ccb7e
comparison
equal deleted inserted replaced
20:f664eeb55cb4 21:72ce60cb1711
21 context->linebuf = malloc(LINEBUF_SIZE + 48); 21 context->linebuf = malloc(LINEBUF_SIZE + 48);
22 context->tmp_buf_a = context->linebuf + LINEBUF_SIZE; 22 context->tmp_buf_a = context->linebuf + LINEBUF_SIZE;
23 context->tmp_buf_b = context->tmp_buf_a + 24; 23 context->tmp_buf_b = context->tmp_buf_a + 24;
24 } 24 }
25 25
26 void render_sprite_cells(uint32_t linecyc, vdp_context * context) 26 void render_sprite_cells(vdp_context * context)
27 { 27 {
28 if (linecyc < context->sprite_draws) { 28 if (context->cur_slot >= context->sprite_draws) {
29 sprite_draw * d = context->sprite_draw_list + linecyc; 29 sprite_draw * d = context->sprite_draw_list + context->cur_slot;
30 context->cur_slot--;
30 uint16_t dir; 31 uint16_t dir;
31 int16_t x; 32 int16_t x;
32 if (d->h_flip) { 33 if (d->h_flip) {
33 x = d->x_pos + 7; 34 x = d->x_pos + 7;
34 dir = -1; 35 dir = -1;
52 void scan_sprite_table(uint32_t line, vdp_context * context) 53 void scan_sprite_table(uint32_t line, vdp_context * context)
53 { 54 {
54 if (context->sprite_index && context->slot_counter) { 55 if (context->sprite_index && context->slot_counter) {
55 line += 1; 56 line += 1;
56 line &= 0xFF; 57 line &= 0xFF;
57 line += 128;
58 context->sprite_index &= 0x7F; 58 context->sprite_index &= 0x7F;
59 //TODO: Read from SAT cache rather than from VRAM 59 //TODO: Read from SAT cache rather than from VRAM
60 uint16_t sat_address = (context->regs[REG_SAT] & 0x7F) << 9; 60 uint16_t sat_address = (context->regs[REG_SAT] & 0x7F) << 9;
61 uint16_t address = context->sprite_index * 8 + sat_address; 61 uint16_t address = context->sprite_index * 8 + sat_address;
62 uint16_t y = ((context->vdpmem[address] & 0x3) << 8 | context->vdpmem[address+1]) - 128; 62 int16_t y = ((context->vdpmem[address] & 0x3) << 8 | context->vdpmem[address+1]) - 128;
63 uint8_t height = ((context->vdpmem[address+2] & 0x3) + 1) * 8; 63 uint8_t height = ((context->vdpmem[address+2] & 0x3) + 1) * 8;
64 if (y >= line && (y + height) < line) { 64 //printf("Sprite %d | y: %d, height: %d\n", context->sprite_index, y, height);
65 if (y <= line && line < (y + height)) {
66 printf("Sprite %d at y: %d with height %d is on line %d\n", context->sprite_index, y, height, line);
65 context->sprite_info_list[--(context->slot_counter)].size = context->vdpmem[address+2]; 67 context->sprite_info_list[--(context->slot_counter)].size = context->vdpmem[address+2];
66 context->sprite_info_list[context->slot_counter].index = context->sprite_index; 68 context->sprite_info_list[context->slot_counter].index = context->sprite_index;
67 context->sprite_info_list[context->slot_counter].y = y; 69 context->sprite_info_list[context->slot_counter].y = y;
68 } 70 }
69 context->sprite_index = context->vdpmem[address+3] & 0x7F; 71 context->sprite_index = context->vdpmem[address+3] & 0x7F;
70 if (context->sprite_index && context->slot_counter) 72 if (context->sprite_index && context->slot_counter)
71 { 73 {
72 address = context->sprite_index * 8 + sat_address; 74 address = context->sprite_index * 8 + sat_address;
73 y = ((context->vdpmem[address] & 0x3) << 8 | context->vdpmem[address+1]) - 128; 75 y = ((context->vdpmem[address] & 0x3) << 8 | context->vdpmem[address+1]) - 128;
74 height = ((context->vdpmem[address+2] & 0x3) + 1) * 8; 76 height = ((context->vdpmem[address+2] & 0x3) + 1) * 8;
75 if (y >= line && y < (line + height)) { 77 if (y <= line && line < (y + height)) {
78 printf("Sprite %d at y: %d with height %d is on line %d\n", context->sprite_index, y, height, line);
76 context->sprite_info_list[--(context->slot_counter)].size = context->vdpmem[address+2]; 79 context->sprite_info_list[--(context->slot_counter)].size = context->vdpmem[address+2];
77 context->sprite_info_list[context->slot_counter].index = context->sprite_index; 80 context->sprite_info_list[context->slot_counter].index = context->sprite_index;
78 context->sprite_info_list[context->slot_counter].y = y; 81 context->sprite_info_list[context->slot_counter].y = y;
79 } 82 }
83 context->sprite_index = context->vdpmem[address+3] & 0x7F;
80 } 84 }
81 } 85 }
82 } 86 }
83 87
84 void read_sprite_x(uint32_t line, vdp_context * context) 88 void read_sprite_x(uint32_t line, vdp_context * context)
85 { 89 {
86 if (context->slot_counter && context->sprite_draws) { 90 if ((context->cur_slot >= context->slot_counter) && context->sprite_draws) {
87 context->slot_counter--; 91 line += 1;
88 uint8_t width = (context->sprite_info_list[context->slot_counter].size & 0x3) + 1; 92 line &= 0xFF;
89 uint8_t height = (((context->sprite_info_list[context->slot_counter].size >> 2) & 0x3) + 1) * 8; 93 //in tiles
90 uint16_t att_addr = ((context->regs[REG_SAT] & 0x7F) << 9) + context->sprite_info_list[context->slot_counter].index * 8 + 4; 94 uint8_t width = ((context->sprite_info_list[context->cur_slot].size >> 2) & 0x3) + 1;
95 //in pixels
96 uint8_t height = ((context->sprite_info_list[context->cur_slot].size & 0x3) + 1) * 8;
97 uint16_t att_addr = ((context->regs[REG_SAT] & 0x7F) << 9) + context->sprite_info_list[context->cur_slot].index * 8 + 4;
91 uint16_t tileinfo = (context->vdpmem[att_addr] << 8) | context->vdpmem[att_addr+1]; 98 uint16_t tileinfo = (context->vdpmem[att_addr] << 8) | context->vdpmem[att_addr+1];
92 uint8_t pal_priority = (tileinfo >> 9) & 0x70; 99 uint8_t pal_priority = (tileinfo >> 9) & 0x70;
93 uint8_t row; 100 uint8_t row;
94 if (tileinfo & MAP_BIT_V_FLIP) { 101 if (tileinfo & MAP_BIT_V_FLIP) {
95 row = (context->sprite_info_list[context->slot_counter].y + height - 1) - line; 102 row = (context->sprite_info_list[context->cur_slot].y + height - 1) - line;
96 } else { 103 } else {
97 row = line-context->sprite_info_list[context->slot_counter].y; 104 row = line-context->sprite_info_list[context->cur_slot].y;
98 } 105 }
99 uint16_t address = ((tileinfo & 0x7FF) << 5) + row * width * 4; 106 uint16_t address = ((tileinfo & 0x7FF) << 5) + (row & 0x7) * 4 + (row & 0x18) * width * 4;
100 int16_t x = ((context->vdpmem[att_addr+ 6] & 0x3) << 8) | context->vdpmem[att_addr + 7]; 107 int16_t x = ((context->vdpmem[att_addr+ 2] & 0x3) << 8) | context->vdpmem[att_addr + 3];
101 if (x) { 108 if (x) {
102 x -= 128; 109 x -= 128;
103 for (;width && context->sprite_draws; --width, --context->sprite_draws, address += 4, x += 8) { 110 printf("Sprite %d | x: %d, y: %d, width: %d, height: %d, pal_priority: %X, row: %d, tile addr: %X\n", context->sprite_info_list[context->cur_slot].index, x, context->sprite_info_list[context->cur_slot].y, width, height, pal_priority, row, address);
111 for (;width && context->sprite_draws; --width, --context->sprite_draws, address += 32, x += 8) {
104 context->sprite_draw_list[context->sprite_draws].address = address; 112 context->sprite_draw_list[context->sprite_draws].address = address;
105 context->sprite_draw_list[context->sprite_draws].x_pos = x; 113 context->sprite_draw_list[context->sprite_draws].x_pos = x;
106 context->sprite_draw_list[context->sprite_draws].pal_priority = pal_priority; 114 context->sprite_draw_list[context->sprite_draws].pal_priority = pal_priority;
107 context->sprite_draw_list[context->sprite_draws].h_flip = (tileinfo & MAP_BIT_H_FLIP) ? 1 : 0; 115 context->sprite_draw_list[context->sprite_draws].h_flip = (tileinfo & MAP_BIT_H_FLIP) ? 1 : 0;
108 } 116 }
117 context->cur_slot--;
109 } else { 118 } else {
110 //sprite masking enabled, no more sprites on this line 119 //sprite masking enabled, no more sprites on this line
111 context->slot_counter = 0; 120 context->cur_slot = -1;
112 } 121 }
113 } 122 }
114 } 123 }
115 124
116 void external_slot(vdp_context * context) 125 void external_slot(vdp_context * context)
243 } else {*/ 252 } else {*/
244 end = dst + 16; 253 end = dst + 16;
245 //} 254 //}
246 for (; dst < end; ++plane_a, ++plane_b, ++sprite_buf, ++dst) { 255 for (; dst < end; ++plane_a, ++plane_b, ++sprite_buf, ++dst) {
247 uint8_t pixel; 256 uint8_t pixel;
248 if (*sprite_buf & BUF_BIT_PRIORITY) { 257 if (*sprite_buf & BUF_BIT_PRIORITY && *sprite_buf & 0xF) {
249 pixel = *sprite_buf; 258 pixel = *sprite_buf;
250 } else if (*plane_a & BUF_BIT_PRIORITY) { 259 } else if (*plane_a & BUF_BIT_PRIORITY && *plane_a & 0xF) {
251 pixel = *plane_a; 260 pixel = *plane_a;
252 } else if (*plane_b & BUF_BIT_PRIORITY) { 261 } else if (*plane_b & BUF_BIT_PRIORITY && *plane_b & 0xF) {
253 pixel = *plane_b; 262 pixel = *plane_b;
254 } else if (*sprite_buf & 0xF) { 263 } else if (*sprite_buf & 0xF) {
255 pixel = *sprite_buf; 264 pixel = *sprite_buf;
256 } else if (*plane_a & 0xF) { 265 } else if (*plane_a & 0xF) {
257 pixel = *plane_a; 266 pixel = *plane_a;
333 uint32_t mask; 342 uint32_t mask;
334 switch(linecyc) 343 switch(linecyc)
335 { 344 {
336 //sprite render to line buffer starts 345 //sprite render to line buffer starts
337 case 0: 346 case 0:
347 context->cur_slot = MAX_DRAWS;
338 memset(context->linebuf, 0, LINEBUF_SIZE); 348 memset(context->linebuf, 0, LINEBUF_SIZE);
339 render_sprite_cells(linecyc, context); 349 render_sprite_cells(context);
340 break; 350 break;
341 case 1: 351 case 1:
342 case 2: 352 case 2:
343 case 3: 353 case 3:
344 render_sprite_cells(linecyc, context); 354 render_sprite_cells(context);
345 break; 355 break;
346 //sprite attribute table scan starts 356 //sprite attribute table scan starts
347 case 4: 357 case 4:
348 render_sprite_cells(linecyc, context); 358 render_sprite_cells( context);
349 context->sprite_index = 0x80; 359 context->sprite_index = 0x80;
350 context->slot_counter = MAX_SPRITES_LINE; 360 context->slot_counter = MAX_SPRITES_LINE;
351 scan_sprite_table(line, context); 361 scan_sprite_table(line, context);
352 break; 362 break;
353 case 5: 363 case 5:
367 case 19: 377 case 19:
368 case 20: 378 case 20:
369 //!HSYNC asserted 379 //!HSYNC asserted
370 case 21: 380 case 21:
371 case 22: 381 case 22:
372 render_sprite_cells(linecyc, context); 382 render_sprite_cells(context);
373 scan_sprite_table(line, context); 383 scan_sprite_table(line, context);
374 break; 384 break;
375 case 23: 385 case 23:
376 external_slot(context); 386 external_slot(context);
377 break; 387 break;
384 case 30: 394 case 30:
385 case 31: 395 case 31:
386 case 32: 396 case 32:
387 case 33: 397 case 33:
388 case 34: 398 case 34:
389 render_sprite_cells(linecyc, context); 399 render_sprite_cells(context);
390 scan_sprite_table(line, context); 400 scan_sprite_table(line, context);
391 break; 401 break;
392 case 35: 402 case 35:
393 address = (context->regs[REG_HSCROLL] & 0x3F) << 10; 403 address = (context->regs[REG_HSCROLL] & 0x3F) << 10;
394 mask = 0; 404 mask = 0;
407 case 36: 417 case 36:
408 //!HSYNC high 418 //!HSYNC high
409 case 37: 419 case 37:
410 case 38: 420 case 38:
411 case 39: 421 case 39:
412 render_sprite_cells(linecyc, context); 422 render_sprite_cells(context);
413 scan_sprite_table(line, context); 423 scan_sprite_table(line, context);
414 break; 424 break;
415 case 40: 425 case 40:
416 read_map_scroll_a(0, line, context); 426 read_map_scroll_a(0, line, context);
417 break; 427 break;
418 case 41: 428 case 41:
419 render_sprite_cells(linecyc, context); 429 render_sprite_cells(context);
420 scan_sprite_table(line, context); 430 scan_sprite_table(line, context);
421 break; 431 break;
422 case 42: 432 case 42:
423 render_map_1(context); 433 render_map_1(context);
424 scan_sprite_table(line, context);//Just a guess 434 scan_sprite_table(line, context);//Just a guess
429 break; 439 break;
430 case 44: 440 case 44:
431 read_map_scroll_b(0, line, context); 441 read_map_scroll_b(0, line, context);
432 break; 442 break;
433 case 45: 443 case 45:
434 render_sprite_cells(linecyc, context); 444 render_sprite_cells(context);
435 scan_sprite_table(line, context); 445 scan_sprite_table(line, context);
436 break; 446 break;
437 case 46: 447 case 46:
438 render_map_3(context); 448 render_map_3(context);
439 scan_sprite_table(line, context);//Just a guess 449 scan_sprite_table(line, context);//Just a guess
441 case 47: 451 case 47:
442 render_map_output(line, 0, context); 452 render_map_output(line, 0, context);
443 scan_sprite_table(line, context);//Just a guess 453 scan_sprite_table(line, context);//Just a guess
444 //reverse context slot counter so it counts the number of sprite slots 454 //reverse context slot counter so it counts the number of sprite slots
445 //filled rather than the number of available slots 455 //filled rather than the number of available slots
446 context->slot_counter = MAX_SPRITES_LINE - context->slot_counter; 456 //context->slot_counter = MAX_SPRITES_LINE - context->slot_counter;
457 context->cur_slot = MAX_SPRITES_LINE-1;
447 context->sprite_draws = MAX_DRAWS; 458 context->sprite_draws = MAX_DRAWS;
448 break; 459 break;
449 COLUMN_RENDER_BLOCK(2, 48) 460 COLUMN_RENDER_BLOCK(2, 48)
450 COLUMN_RENDER_BLOCK(4, 56) 461 COLUMN_RENDER_BLOCK(4, 56)
451 COLUMN_RENDER_BLOCK(6, 64) 462 COLUMN_RENDER_BLOCK(6, 64)