comparison vdp.c @ 26:a7c2b92d8056

Fix management of context->sprite_draws so the sprite layer only draws when it should
author Mike Pavone <pavone@retrodev.com>
date Sat, 08 Dec 2012 16:46:47 -0800
parents 4d0c20ad815a
children aa1c47fab3f1
comparison
equal deleted inserted replaced
25:4d0c20ad815a 26:a7c2b92d8056
19 context->vdpmem = malloc(VRAM_SIZE); 19 context->vdpmem = malloc(VRAM_SIZE);
20 context->framebuf = malloc(FRAMEBUF_SIZE); 20 context->framebuf = malloc(FRAMEBUF_SIZE);
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 context->sprite_draws = MAX_DRAWS;
24 } 25 }
25 26
26 void render_sprite_cells(vdp_context * context) 27 void render_sprite_cells(vdp_context * context)
27 { 28 {
28 if (context->cur_slot >= context->sprite_draws) { 29 if (context->cur_slot >= context->sprite_draws) {
29 sprite_draw * d = context->sprite_draw_list + context->cur_slot; 30 sprite_draw * d = context->sprite_draw_list + context->cur_slot;
30 context->cur_slot--; 31
31 uint16_t dir; 32 uint16_t dir;
32 int16_t x; 33 int16_t x;
33 if (d->h_flip) { 34 if (d->h_flip) {
34 x = d->x_pos + 7; 35 x = d->x_pos + 7;
35 dir = -1; 36 dir = -1;
36 } else { 37 } else {
37 x = d->x_pos; 38 x = d->x_pos;
38 dir = 1; 39 dir = 1;
39 } 40 }
41 printf("Draw Slot %d of %d, Rendering sprite cell from %X to x: %d\n", context->cur_slot, context->sprite_draws, d->address, x);
42 context->cur_slot--;
40 for (uint16_t address = d->address; address < d->address+4; address++) { 43 for (uint16_t address = d->address; address < d->address+4; address++) {
41 if (x >= 0 && x < 320) { 44 if (x >= 0 && x < 320) {
42 context->linebuf[x] = (context->vdpmem[address] >> 4) | d->pal_priority; 45 context->linebuf[x] = (context->vdpmem[address] >> 4) | d->pal_priority;
43 } 46 }
44 x += dir; 47 x += dir;
61 uint16_t address = context->sprite_index * 8 + sat_address; 64 uint16_t address = context->sprite_index * 8 + sat_address;
62 int16_t y = ((context->vdpmem[address] & 0x3) << 8 | context->vdpmem[address+1]) - 128; 65 int16_t y = ((context->vdpmem[address] & 0x3) << 8 | context->vdpmem[address+1]) - 128;
63 uint8_t height = ((context->vdpmem[address+2] & 0x3) + 1) * 8; 66 uint8_t height = ((context->vdpmem[address+2] & 0x3) + 1) * 8;
64 //printf("Sprite %d | y: %d, height: %d\n", context->sprite_index, y, height); 67 //printf("Sprite %d | y: %d, height: %d\n", context->sprite_index, y, height);
65 if (y <= line && line < (y + height)) { 68 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); 69 printf("Sprite %d at y: %d with height %d is on line %d\n", context->sprite_index, y, height, line);
67 context->sprite_info_list[--(context->slot_counter)].size = context->vdpmem[address+2]; 70 context->sprite_info_list[--(context->slot_counter)].size = context->vdpmem[address+2];
68 context->sprite_info_list[context->slot_counter].index = context->sprite_index; 71 context->sprite_info_list[context->slot_counter].index = context->sprite_index;
69 context->sprite_info_list[context->slot_counter].y = y; 72 context->sprite_info_list[context->slot_counter].y = y;
70 } 73 }
71 context->sprite_index = context->vdpmem[address+3] & 0x7F; 74 context->sprite_index = context->vdpmem[address+3] & 0x7F;
73 { 76 {
74 address = context->sprite_index * 8 + sat_address; 77 address = context->sprite_index * 8 + sat_address;
75 y = ((context->vdpmem[address] & 0x3) << 8 | context->vdpmem[address+1]) - 128; 78 y = ((context->vdpmem[address] & 0x3) << 8 | context->vdpmem[address+1]) - 128;
76 height = ((context->vdpmem[address+2] & 0x3) + 1) * 8; 79 height = ((context->vdpmem[address+2] & 0x3) + 1) * 8;
77 if (y <= line && line < (y + height)) { 80 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); 81 printf("Sprite %d at y: %d with height %d is on line %d\n", context->sprite_index, y, height, line);
79 context->sprite_info_list[--(context->slot_counter)].size = context->vdpmem[address+2]; 82 context->sprite_info_list[--(context->slot_counter)].size = context->vdpmem[address+2];
80 context->sprite_info_list[context->slot_counter].index = context->sprite_index; 83 context->sprite_info_list[context->slot_counter].index = context->sprite_index;
81 context->sprite_info_list[context->slot_counter].y = y; 84 context->sprite_info_list[context->slot_counter].y = y;
82 } 85 }
83 context->sprite_index = context->vdpmem[address+3] & 0x7F; 86 context->sprite_index = context->vdpmem[address+3] & 0x7F;
107 uint16_t address = ((tileinfo & 0x7FF) << 5) + row * 4; 110 uint16_t address = ((tileinfo & 0x7FF) << 5) + row * 4;
108 int16_t x = ((context->vdpmem[att_addr+ 2] & 0x3) << 8) | context->vdpmem[att_addr + 3]; 111 int16_t x = ((context->vdpmem[att_addr+ 2] & 0x3) << 8) | context->vdpmem[att_addr + 3];
109 if (x) { 112 if (x) {
110 x -= 128; 113 x -= 128;
111 int16_t base_x = x; 114 int16_t base_x = x;
112 //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); 115 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);
113 for (;width && context->sprite_draws; --width, --context->sprite_draws, x += 8) { 116 for (;width && context->sprite_draws; --width, x += 8) {
117 --context->sprite_draws;
114 context->sprite_draw_list[context->sprite_draws].address = address + ((x-base_x) / 8) * height * 4; 118 context->sprite_draw_list[context->sprite_draws].address = address + ((x-base_x) / 8) * height * 4;
115 context->sprite_draw_list[context->sprite_draws].x_pos = x; 119 context->sprite_draw_list[context->sprite_draws].x_pos = x;
116 context->sprite_draw_list[context->sprite_draws].pal_priority = pal_priority; 120 context->sprite_draw_list[context->sprite_draws].pal_priority = pal_priority;
117 context->sprite_draw_list[context->sprite_draws].h_flip = (tileinfo & MAP_BIT_H_FLIP) ? 1 : 0; 121 context->sprite_draw_list[context->sprite_draws].h_flip = (tileinfo & MAP_BIT_H_FLIP) ? 1 : 0;
118 } 122 }
148 vscroll = 0x3FF; 152 vscroll = 0x3FF;
149 break; 153 break;
150 } 154 }
151 vscroll &= (context->vsram[(context->regs[REG_MODE_3] & 0x4 ? column : 0) + vsram_off] + line); 155 vscroll &= (context->vsram[(context->regs[REG_MODE_3] & 0x4 ? column : 0) + vsram_off] + line);
152 context->v_offset = vscroll & 0x7; 156 context->v_offset = vscroll & 0x7;
153 printf("BG | line %d, vsram: %d, vscroll: %d, v_offset: %d\n", line, context->vsram[context->regs[REG_MODE_3] & 0x4 ? column : 0], vscroll, context->v_offset); 157 //printf("%s | line %d, vsram: %d, vscroll: %d, v_offset: %d\n",(vsram_off ? "B" : "A"), line, context->vsram[context->regs[REG_MODE_3] & 0x4 ? column : 0], vscroll, context->v_offset);
154 vscroll /= 8; 158 vscroll /= 8;
155 uint16_t hscroll_mask; 159 uint16_t hscroll_mask;
156 uint16_t v_mul; 160 uint16_t v_mul;
157 switch(context->regs[REG_SCROLL] & 0x3) 161 switch(context->regs[REG_SCROLL] & 0x3)
158 { 162 {
174 v_mul = 256; 178 v_mul = 256;
175 break; 179 break;
176 } 180 }
177 uint16_t hscroll = (hscroll_val + (column-2) * 8) & hscroll_mask; 181 uint16_t hscroll = (hscroll_val + (column-2) * 8) & hscroll_mask;
178 uint16_t offset = address + ((vscroll * v_mul + hscroll/4) & 0x1FFF); 182 uint16_t offset = address + ((vscroll * v_mul + hscroll/4) & 0x1FFF);
179 printf("BG | line: %d, col: %d, x: %d, hs_mask %X, v_mul: %d, scr reg: %X, tbl addr: %X\n", line, column, hscroll, hscroll_mask, v_mul, context->regs[REG_SCROLL], offset); 183 //printf("%s | line: %d, col: %d, x: %d, hs_mask %X, v_mul: %d, scr reg: %X, tbl addr: %X\n", (vsram_off ? "B" : "A"), line, column, hscroll, hscroll_mask, v_mul, context->regs[REG_SCROLL], offset);
180 context->col_1 = (context->vdpmem[offset] << 8) | context->vdpmem[offset+1]; 184 context->col_1 = (context->vdpmem[offset] << 8) | context->vdpmem[offset+1];
181 hscroll = (hscroll_val + (column-1) * 8) & hscroll_mask; 185 hscroll = (hscroll_val + (column-1) * 8) & hscroll_mask;
182 offset = address + ((vscroll * v_mul + hscroll/4) & 0x1FFF); 186 offset = address + ((vscroll * v_mul + hscroll/4) & 0x1FFF);
183 context->col_2 = (context->vdpmem[offset] << 8) | context->vdpmem[offset+1]; 187 context->col_2 = (context->vdpmem[offset] << 8) | context->vdpmem[offset+1];
184 } 188 }
344 uint32_t mask; 348 uint32_t mask;
345 switch(linecyc) 349 switch(linecyc)
346 { 350 {
347 //sprite render to line buffer starts 351 //sprite render to line buffer starts
348 case 0: 352 case 0:
349 context->cur_slot = MAX_DRAWS; 353 context->cur_slot = MAX_DRAWS-1;
350 memset(context->linebuf, 0, LINEBUF_SIZE); 354 memset(context->linebuf, 0, LINEBUF_SIZE);
351 render_sprite_cells(context); 355 render_sprite_cells(context);
352 break; 356 break;
353 case 1: 357 case 1:
354 case 2: 358 case 2:
478 COLUMN_RENDER_BLOCK(34, 176) 482 COLUMN_RENDER_BLOCK(34, 176)
479 COLUMN_RENDER_BLOCK(36, 184) 483 COLUMN_RENDER_BLOCK(36, 184)
480 COLUMN_RENDER_BLOCK(38, 192) 484 COLUMN_RENDER_BLOCK(38, 192)
481 COLUMN_RENDER_BLOCK_REFRESH(40, 200) 485 COLUMN_RENDER_BLOCK_REFRESH(40, 200)
482 case 208: 486 case 208:
483 context->sprite_draws = MAX_DRAWS - context->sprite_draws;
484 case 209: 487 case 209:
485 external_slot(context); 488 external_slot(context);
486 break; 489 break;
487 default: 490 default:
488 //leftovers from HSYNC clock change nonsense 491 //leftovers from HSYNC clock change nonsense