nuclear@5: #include "config.h" nuclear@5: #include nuclear@6: #include nuclear@5: #include "polyfill.h" nuclear@5: #include "fixed.h" nuclear@5: #include "gbasys.h" nuclear@5: nuclear@5: static void fill_scanline(int y, int x0, int x1, uint16_t color); nuclear@5: nuclear@5: void draw_poly(int num, const pvec3 *verts, uint16_t color) nuclear@5: { nuclear@5: int i, topidx = 0, botidx = 0; nuclear@5: int lidx[2], ridx[2]; nuclear@5: int32_t y, topy, boty; nuclear@5: int32_t ldy, rdy, ldxdy, rdxdy; nuclear@5: int32_t lx, rx; nuclear@5: int start, end; nuclear@5: nuclear@5: topy = boty = verts[0].y; nuclear@5: for(i=1; i boty) { nuclear@5: boty = y; nuclear@5: botidx = i; nuclear@5: } nuclear@5: } nuclear@5: nuclear@5: lidx[0] = ridx[0] = topidx; nuclear@5: lidx[1] = topidx ? topidx - 1 : num - 1; nuclear@5: ridx[1] = (topidx + 1) % num; nuclear@5: nuclear@6: if(verts[ridx[1]].x < verts[lidx[1]].x) { nuclear@5: return; /* backface (CCW) */ nuclear@5: } nuclear@5: nuclear@5: lx = rx = verts[lidx[0]].x; nuclear@5: nuclear@6: /* TODO handle ldy == 0 or rdy == 0 */ nuclear@5: ldy = verts[lidx[1]].y - verts[lidx[0]].y; nuclear@5: ldxdy = x16div(verts[lidx[1]].x - lx, ldy); nuclear@5: nuclear@6: rdy = verts[ridx[1]].y - verts[ridx[0]].y; nuclear@5: rdxdy = x16div(verts[ridx[1]].x - rx, rdy); nuclear@5: nuclear@5: start = topy >> 16; nuclear@5: end = boty >> 16; nuclear@5: nuclear@6: if(end >= HEIGHT) end = HEIGHT - 1; nuclear@6: nuclear@5: y = topy; nuclear@5: for(i=start; i> 16); nuclear@6: x1 = (rx >> 16) >= WIDTH ? WIDTH - 1 : (rx >> 16); nuclear@5: nuclear@6: if(i >= 0 && x1 > x0) { nuclear@6: fill_scanline(i, x0, x1, color); nuclear@6: } nuclear@5: nuclear@5: if(y >= verts[lidx[1]].y) { nuclear@5: lidx[0] = lidx[1]; nuclear@5: lidx[1] = lidx[1] ? lidx[1] - 1 : num - 1; nuclear@5: ldy = verts[lidx[1]].y - verts[lidx[0]].y; nuclear@5: if(ldy < 0) { nuclear@5: break; nuclear@5: } nuclear@5: ldxdy = x16div(verts[lidx[1]].x - lx, ldy); nuclear@5: } nuclear@5: if(y >= verts[ridx[1]].y) { nuclear@5: ridx[0] = ridx[1]; nuclear@5: ridx[1] = (ridx[1] + 1) % num; nuclear@5: rdy = verts[ridx[1]].y - verts[ridx[0]].y; nuclear@5: if(rdy < 0) { nuclear@5: break; nuclear@5: } nuclear@5: rdxdy = x16div(verts[ridx[1]].x - rx, rdy); nuclear@5: } nuclear@5: nuclear@5: lx += ldxdy; nuclear@5: rx += rdxdy; nuclear@6: y += 65536; nuclear@5: } nuclear@5: } nuclear@5: nuclear@5: static void fill_scanline(int y, int x0, int x1, uint16_t color) nuclear@5: { nuclear@5: int i; nuclear@5: uint16_t *pixels = (uint16_t*)back_buffer->pixels + y * WIDTH + x0; nuclear@5: nuclear@5: for(i=x0; i