2 blender for the Gameboy Advance
3 Copyright (C) 2021 John Tsiombikas <nuclear@member.fsf.org>
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <https://www.gnu.org/licenses/>.
22 static unsigned char *fb;
23 static int fbwidth, fbheight;
24 static short scantab[2][160] __attribute__((section(".iwram")));
26 void polyfill_framebuffer(unsigned char *ptr, int w, int h)
33 #define VNEXT(p) (((p) == vlast) ? varr : (p) + 1)
34 #define VPREV(p) ((p) == varr ? vlast : (p) - 1)
35 #define VSUCC(p, side) ((side) == 0 ? VNEXT(p) : VPREV(p))
37 void polyfill_flat(struct pvertex *varr, int vnum, unsigned char col)
39 int i, line, top, bot;
40 struct pvertex *vlast, *v, *vn;
41 int32_t x, y0, y1, dx, dy, slope, fx, fy;
42 short *tab, start, len;
45 vlast = varr + vnum - 1;
49 for(i=0; i<vnum; i++) {
53 if(vn->y == v->y) continue;
65 slope = (dx << 8) / dy;
67 y0 = (v->y + 0x100) & 0xffffff00; /* start from the next scanline */
68 fy = y0 - v->y; /* fractional part before the next scanline */
69 fx = (fy * slope) >> 8; /* X adjust for the step to the next scanline */
70 x = v->x + fx; /* adjust X */
71 y1 = vn->y & 0xffffff00; /* last scanline of the edge <= vn->y */
74 if(line < top) top = line;
75 if((y1 >> 8) > bot) bot = y1 >> 8;
77 if(line > 0) tab += line;
79 while(line < (y1 >> 8) && line < fbheight) {
81 int val = x < 0 ? 0 : x >> 8;
82 *tab++ = val < fbwidth ? val : fbwidth - 1;
89 fbptr = fb + top * fbwidth;
90 for(i=top; i<bot; i++) {
91 start = scantab[0][i];
92 len = scantab[1][i] - start;
95 memset(fbptr + start, col, len);