Mercurial > repos > simple16
comparison src/vdp.c @ 22:407725d9a02f
Implemented sprite drawing. Added small sprite example.
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Wed, 30 Mar 2016 19:55:48 -0700 |
parents | 91ded3b12d96 |
children | a085f17b79e9 |
comparison
equal
deleted
inserted
replaced
21:91ded3b12d96 | 22:407725d9a02f |
---|---|
39 } else { | 39 } else { |
40 context->drawbuffer = context->linebuffers; | 40 context->drawbuffer = context->linebuffers; |
41 context->readbuffer = context->linebuffers + 328; | 41 context->readbuffer = context->linebuffers + 328; |
42 } | 42 } |
43 context->draw_dest = 0; | 43 context->draw_dest = 0; |
44 //enable sprite scanning | |
45 context->status |= VDP_STATUS_SPRITE_SCAN; | |
46 context->current_draw = 0; | |
44 } | 47 } |
45 if (context->draw_counter) { | 48 if (context->draw_counter) { |
46 context->draw_counter--; | 49 context->draw_counter--; |
47 uint16_t pixels = context->vram[context->draw_source++]; | 50 uint16_t pixels = context->vram[context->draw_source++]; |
48 for (int i = 0; i < 4; i++) | 51 for (int i = 0; i < 4; i++) |
68 } | 71 } |
69 context->palpriority = entry >> 9 & 0x70; | 72 context->palpriority = entry >> 9 & 0x70; |
70 context->draw_counter = 2; | 73 context->draw_counter = 2; |
71 //TODO: handle horizontal flip | 74 //TODO: handle horizontal flip |
72 } | 75 } |
73 //TODO: Scan sprite table | 76 if (context->status & VDP_STATUS_SPRITE_SCAN) { |
77 context->status |= VDP_STATUS_SRAM; | |
78 uint16_t pos = context->sram[context->hcounter]; | |
79 uint16_t y = pos & 0xFF; | |
80 uint16_t x = pos >> 8; | |
81 uint16_t atts = context->sram[context->hcounter+1]; | |
82 x |= atts << 2 & 0x100; | |
83 if (x | y) { | |
84 uint16_t size = atts & 0x400 ? 16 : 8; | |
85 if (context->vcounter >= y && context->vcounter < y + size) { | |
86 uint16_t address = (atts & 0x3F) * 16; | |
87 if (atts & 0x1000) { | |
88 address += (size-1) * 2 - (context->vcounter - y) * 2; | |
89 } else { | |
90 address += (context->vcounter - y) * 2; | |
91 } | |
92 context->sprite_draws[context->current_draw].source = address; | |
93 context->sprite_draws[context->current_draw].x = x; | |
94 context->sprite_draws[context->current_draw].hflip = (atts & 0x800) != 0; | |
95 context->sprite_draws[context->current_draw].palpriority = 0x80 | (atts >> 9 & 0x50); | |
96 context->current_draw++; | |
97 if (size == 16) { | |
98 context->sprite_draws[context->current_draw].source = address + 32; | |
99 context->sprite_draws[context->current_draw].x = x + 8; | |
100 context->sprite_draws[context->current_draw].hflip = (atts & 0x800) != 0; | |
101 context->sprite_draws[context->current_draw].palpriority = 0x80 | (atts >> 9 & 0x50); | |
102 } | |
103 context->current_draw++; | |
104 if (context->current_draw == 40) { | |
105 //no more rendering capacity | |
106 context->status &= ~VDP_STATUS_SPRITE_SCAN; | |
107 context->current_draw = 0; | |
108 } | |
109 } | |
110 } else { | |
111 //hit sprite list terminator | |
112 context->status &= ~VDP_STATUS_SPRITE_SCAN; | |
113 context->current_draw = 0; | |
114 } | |
115 } | |
74 } else { | 116 } else { |
75 //TODO: Render sprites | 117 sprite_draw *draw = context->sprite_draws + (context->current_draw >> 1); |
118 if (draw->palpriority) { | |
119 context->status |= VDP_STATUS_VRAM; | |
120 uint16_t pixels = context->vram[draw->source + (context->current_draw & 1)]; | |
121 uint16_t x = draw->x - 16 + (context->hscroll & 7); | |
122 for (int i = 0; i < 4; i++, x++) | |
123 { | |
124 //TODO: handle horizontal flip | |
125 uint8_t pixel = (pixels >> ((3-i) * 4)) & 0xF; | |
126 if (pixel && x < 328 && ((draw->palpriority & 0x40) || !(context->drawbuffer[x] & 0x40))) { | |
127 context->drawbuffer[x] = pixel | draw->palpriority; | |
128 } | |
129 } | |
130 if (context->current_draw & 1) { | |
131 draw->palpriority = 0; | |
132 } else { | |
133 draw->x += 4; | |
134 } | |
135 } | |
136 context->current_draw++; | |
76 } | 137 } |
77 } | 138 } |
78 //Draw to framebuffer | 139 //Draw to framebuffer |
79 if (context->vcounter > 8 && context->vcounter < 249 && context->hcounter < 320) { | 140 if (context->vcounter > 8 && context->vcounter < 249 && context->hcounter < 320) { |
80 if (!context->hcounter && context->vcounter == 9) { | 141 if (!context->hcounter && context->vcounter == 9) { |