X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=bootcensus;a=blobdiff_plain;f=src%2Fcensus%2Fgfxutil.c;fp=src%2Fcensus%2Fgfxutil.c;h=647920568dfc969677c6ce1e64939865845df82a;hp=0000000000000000000000000000000000000000;hb=10843571c724084c68d33d0438167d400cc8de2e;hpb=f9194c22d8073b69b3e64fc26b9e245b6b54d009 diff --git a/src/census/gfxutil.c b/src/census/gfxutil.c new file mode 100644 index 0000000..6479205 --- /dev/null +++ b/src/census/gfxutil.c @@ -0,0 +1,217 @@ +#include "gfxutil.h" +#include "census.h" + +enum { + IN = 0, + LEFT = 1, + RIGHT = 2, + TOP = 4, + BOTTOM = 8 +}; + +static int outcode(int x, int y, int xmin, int ymin, int xmax, int ymax) +{ + int code = 0; + + if(x < xmin) { + code |= LEFT; + } else if(x > xmax) { + code |= RIGHT; + } + if(y < ymin) { + code |= TOP; + } else if(y > ymax) { + code |= BOTTOM; + } + return code; +} + +#define FIXMUL(a, b) (((a) * (b)) >> 8) +#define FIXDIV(a, b) (((a) << 8) / (b)) + +#define LERP(a, b, t) ((a) + FIXMUL((b) - (a), (t))) + +int clip_line(int *x0, int *y0, int *x1, int *y1, int xmin, int ymin, int xmax, int ymax) +{ + int oc_out; + + int oc0 = outcode(*x0, *y0, xmin, ymin, xmax, ymax); + int oc1 = outcode(*x1, *y1, xmin, ymin, xmax, ymax); + + long fx0, fy0, fx1, fy1, fxmin, fymin, fxmax, fymax; + + if(!(oc0 | oc1)) return 1; /* both points are inside */ + + fx0 = *x0 << 8; + fy0 = *y0 << 8; + fx1 = *x1 << 8; + fy1 = *y1 << 8; + fxmin = xmin << 8; + fymin = ymin << 8; + fxmax = xmax << 8; + fymax = ymax << 8; + + for(;;) { + long x, y, t; + + if(oc0 & oc1) return 0; /* both have points with the same outbit, not visible */ + if(!(oc0 | oc1)) break; /* both points are inside */ + + oc_out = oc0 ? oc0 : oc1; + + if(oc_out & TOP) { + t = FIXDIV(fymin - fy0, fy1 - fy0); + x = LERP(fx0, fx1, t); + y = fymin; + } else if(oc_out & BOTTOM) { + t = FIXDIV(fymax - fy0, fy1 - fy0); + x = LERP(fx0, fx1, t); + y = fymax; + } else if(oc_out & LEFT) { + t = FIXDIV(fxmin - fx0, fx1 - fx0); + x = fxmin; + y = LERP(fy0, fy1, t); + } else if(oc_out & RIGHT) { + t = FIXDIV(fxmax - fx0, fx1 - fx0); + x = fxmax; + y = LERP(fy0, fy1, t); + } + + if(oc_out == oc0) { + fx0 = x; + fy0 = y; + oc0 = outcode(fx0 >> 8, fy0 >> 8, xmin, ymin, xmax, ymax); + } else { + fx1 = x; + fy1 = y; + oc1 = outcode(fx1 >> 8, fy1 >> 8, xmin, ymin, xmax, ymax); + } + } + + *x0 = fx0 >> 8; + *y0 = fy0 >> 8; + *x1 = fx1 >> 8; + *y1 = fy1 >> 8; + return 1; +} + +void draw_line(int x0, int y0, int x1, int y1, uint32_t color) +{ + int i, dx, dy, x_inc, y_inc, error; + uint32_t *fb = fb_pixels; + + fb += y0 * fb_width + x0; + + dx = x1 - x0; + dy = y1 - y0; + + if(dx >= 0) { + x_inc = 1; + } else { + x_inc = -1; + dx = -dx; + } + if(dy >= 0) { + y_inc = fb_width; + } else { + y_inc = -fb_width; + dy = -dy; + } + + if(dx > dy) { + error = dy * 2 - dx; + for(i=0; i<=dx; i++) { + *fb = color; + if(error >= 0) { + error -= dx * 2; + fb += y_inc; + } + error += dy * 2; + fb += x_inc; + } + } else { + error = dx * 2 - dy; + for(i=0; i<=dy; i++) { + *fb = color; + if(error >= 0) { + error -= dy * 2; + fb += x_inc; + } + error += dx * 2; + fb += y_inc; + } + } +} + + +#define BLUR(w, h, pstep, sstep) \ + for(i=0; i