Mercurial > repos > blastem
comparison vdp.c @ 36:04672c060062
Pass all sprite masking tests
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Sat, 08 Dec 2012 23:09:40 -0800 |
parents | 233c7737c152 |
children | cd59519b26d9 |
comparison
equal
deleted
inserted
replaced
35:233c7737c152 | 36:04672c060062 |
---|---|
87 } | 87 } |
88 } | 88 } |
89 } | 89 } |
90 | 90 |
91 #define FLAG_DOT_OFLOW 0x1 | 91 #define FLAG_DOT_OFLOW 0x1 |
92 #define FLAG_CAN_MASK 0x2 | 92 #define FLAG_CAN_MASK 0x2 |
93 #define FLAG_MASKED 0x4 | |
93 void read_sprite_x(uint32_t line, vdp_context * context) | 94 void read_sprite_x(uint32_t line, vdp_context * context) |
94 { | 95 { |
95 if (context->cur_slot >= context->slot_counter) { | 96 if (context->cur_slot >= context->slot_counter) { |
96 if (context->sprite_draws) { | 97 if (context->sprite_draws) { |
97 line += 1; | 98 line += 1; |
107 if (tileinfo & MAP_BIT_V_FLIP) { | 108 if (tileinfo & MAP_BIT_V_FLIP) { |
108 row = (context->sprite_info_list[context->cur_slot].y + height - 1) - line; | 109 row = (context->sprite_info_list[context->cur_slot].y + height - 1) - line; |
109 } else { | 110 } else { |
110 row = line-context->sprite_info_list[context->cur_slot].y; | 111 row = line-context->sprite_info_list[context->cur_slot].y; |
111 } | 112 } |
112 //uint16_t address = ((tileinfo & 0x7FF) << 5) + (row & 0x7) * 4 + (row & 0x18) * width * 4; | |
113 uint16_t address = ((tileinfo & 0x7FF) << 5) + row * 4; | 113 uint16_t address = ((tileinfo & 0x7FF) << 5) + row * 4; |
114 int16_t x = ((context->vdpmem[att_addr+ 2] & 0x3) << 8) | context->vdpmem[att_addr + 3]; | 114 int16_t x = ((context->vdpmem[att_addr+ 2] & 0x3) << 8) | context->vdpmem[att_addr + 3]; |
115 if (x || !(context->flags & (FLAG_CAN_MASK | FLAG_DOT_OFLOW))) { | 115 if (x) { |
116 //printf("Displaying %d | line: %d, x: %d, flags: %X\n", context->sprite_info_list[context->cur_slot].index, line, x, context->flags); | 116 context->flags |= FLAG_CAN_MASK; |
117 if (x) { | 117 } else if(context->flags & (FLAG_CAN_MASK | FLAG_DOT_OFLOW)) { |
118 context->flags |= FLAG_CAN_MASK; | 118 context->flags |= FLAG_MASKED; |
119 } | |
120 | |
121 context->flags &= ~FLAG_DOT_OFLOW; | |
122 int16_t i; | |
123 if (context->flags & FLAG_MASKED) { | |
124 for (i=0; i < width && context->sprite_draws; i++) { | |
125 --context->sprite_draws; | |
126 context->sprite_draw_list[context->sprite_draws].x_pos = -128; | |
119 } | 127 } |
120 context->flags &= ~FLAG_DOT_OFLOW; | 128 } else { |
121 x -= 128; | 129 x -= 128; |
122 int16_t base_x = x; | 130 int16_t base_x = x; |
123 int16_t dir; | 131 int16_t dir; |
124 if (tileinfo & MAP_BIT_H_FLIP) { | 132 if (tileinfo & MAP_BIT_H_FLIP) { |
125 x += (width-1) * 8; | 133 x += (width-1) * 8; |
126 dir = -8; | 134 dir = -8; |
127 } else { | 135 } else { |
128 dir = 8; | 136 dir = 8; |
129 } | 137 } |
130 //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); | 138 //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); |
131 int16_t i; | |
132 for (i=0; i < width && context->sprite_draws; i++, x += dir) { | 139 for (i=0; i < width && context->sprite_draws; i++, x += dir) { |
133 --context->sprite_draws; | 140 --context->sprite_draws; |
134 context->sprite_draw_list[context->sprite_draws].address = address + i * height * 4; | 141 context->sprite_draw_list[context->sprite_draws].address = address + i * height * 4; |
135 context->sprite_draw_list[context->sprite_draws].x_pos = x; | 142 context->sprite_draw_list[context->sprite_draws].x_pos = x; |
136 context->sprite_draw_list[context->sprite_draws].pal_priority = pal_priority; | 143 context->sprite_draw_list[context->sprite_draws].pal_priority = pal_priority; |
137 context->sprite_draw_list[context->sprite_draws].h_flip = (tileinfo & MAP_BIT_H_FLIP) ? 1 : 0; | 144 context->sprite_draw_list[context->sprite_draws].h_flip = (tileinfo & MAP_BIT_H_FLIP) ? 1 : 0; |
138 } | 145 } |
139 if (i < width) { | |
140 context->flags |= FLAG_DOT_OFLOW; | |
141 } | |
142 context->cur_slot--; | |
143 } else { | |
144 //printf("Masking %d | line: %d, x: %d, flags: %X\n", context->sprite_info_list[context->cur_slot].index, line, x, context->flags); | |
145 //sprite masking enabled, no more sprites on this line | |
146 context->cur_slot = -1; | |
147 } | 146 } |
147 if (i < width) { | |
148 context->flags |= FLAG_DOT_OFLOW; | |
149 } | |
150 context->cur_slot--; | |
148 } else { | 151 } else { |
149 context->flags |= FLAG_DOT_OFLOW; | 152 context->flags |= FLAG_DOT_OFLOW; |
150 } | 153 } |
151 } | 154 } |
152 } | 155 } |
484 //reverse context slot counter so it counts the number of sprite slots | 487 //reverse context slot counter so it counts the number of sprite slots |
485 //filled rather than the number of available slots | 488 //filled rather than the number of available slots |
486 //context->slot_counter = MAX_SPRITES_LINE - context->slot_counter; | 489 //context->slot_counter = MAX_SPRITES_LINE - context->slot_counter; |
487 context->cur_slot = MAX_SPRITES_LINE-1; | 490 context->cur_slot = MAX_SPRITES_LINE-1; |
488 context->sprite_draws = MAX_DRAWS; | 491 context->sprite_draws = MAX_DRAWS; |
489 context->flags &= ~FLAG_CAN_MASK; | 492 context->flags &= (~FLAG_CAN_MASK & ~FLAG_MASKED); |
490 break; | 493 break; |
491 COLUMN_RENDER_BLOCK(2, 48) | 494 COLUMN_RENDER_BLOCK(2, 48) |
492 COLUMN_RENDER_BLOCK(4, 56) | 495 COLUMN_RENDER_BLOCK(4, 56) |
493 COLUMN_RENDER_BLOCK(6, 64) | 496 COLUMN_RENDER_BLOCK(6, 64) |
494 COLUMN_RENDER_BLOCK_REFRESH(8, 72) | 497 COLUMN_RENDER_BLOCK_REFRESH(8, 72) |