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)