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