/* draw antialiased line from (x1, y1) to (x2, y2), with width linewidth * color is an int like 0xRRGGBB */ static void anti_line(int x1, int y1, int x2, int y2, int linewidth, int color) { int dx = abs(x1 - x2); int dy = abs(y1 - y2); int error, sign, tmp; float ipix; int step = linewidth; if (dx >= dy) { if (x1 > x2) { tmp = x1; x1 = x2; x2 = tmp; tmp = y1; y1 = y2; y2 = tmp; } error = dx / 2; if (y2 > y1) sign = step; else sign = -step; putpixel(x1, y1, 1, linewidth, color); while (x1 < x2) { if ((error -= dy) < 0) { y1 += sign; error += dx; } x1 += step; ipix = (float)error / dx; if (sign == step) ipix = 1 - ipix; putpixel(x1, y1, 1, linewidth, color); putpixel(x1, y1 - step, (1 - ipix), linewidth, color); putpixel(x1, y1 + step, ipix, linewidth, color); } putpixel(x2, y2, 1, linewidth, color); } else { if (y1 > y2) { tmp = x1; x1 = x2; x2 = tmp; tmp = y1; y1 = y2; y2 = tmp; } error = dy / 2; if (x2 > x1) sign = step; else sign = -step; putpixel(x1, y1, 1, linewidth, color); while (y1 < y2) { if ((error -= dx) < 0) { x1 += sign; error += dy; } y1 += step; ipix = (float)error / dy; if (sign == step) ipix = 1 - ipix; putpixel(x1 ,y1, 1, linewidth, color); putpixel(x1 - step, y1, (1 - ipix), linewidth, color); putpixel(x1 + step, y1, ipix, linewidth, color); } putpixel(x2, y2, 1, linewidth, color); } } /* put alpha-blended pixel on the backbuffer. Uses floats, could be * optimized, probably */ static void putpixel(int x, int y, float i, int linewidth, int color) { int pos = (y * XMAX * 3) + x * 3; unsigned char r = ((color >> 16) & 0xff) * i + (bm.rgb[pos]) * (1 - i); unsigned char g = ((color >> 8) & 0xff) * i + (bm.rgb[pos + 1]) * (1 - i); unsigned char b = (color & 0xff) * i + (bm.rgb[pos + 2]) * (1 - i); if (linewidth == 1) { bm.rgb[pos] = r; bm.rgb[pos + 1] = g; bm.rgb[pos + 2] = b; } else { int dx, dy; for (dx = x; dx < x + linewidth; dx++) { for (dy = y; dy < y + linewidth; dy++) { pos = (dy * XMAX * 3) + dx * 3; bm.rgb[pos] = r; bm.rgb[pos + 1] = g; bm.rgb[pos + 2] = b; } } } }