diff --git a/src/gray/gline.c b/src/gray/gline.c new file mode 100644 index 0000000..4714204 --- /dev/null +++ b/src/gray/gline.c @@ -0,0 +1,55 @@ +#include +#include +#include + +/* gline(): Bresenham line drawing algorithm + Remotely adapted from MonochromeLib code by Pierre "PerriotLL" Le Gall. + Relies on grect() for optimized situations. + @x1 @y1 @x2 @y2 Coordinates of endpoints of line (included) + @color Any color */ +void gline(int x1, int y1, int x2, int y2, color_t color) +{ + /* Trivial optimizations */ + if(x1 == x2 || y1 == y2) + { + grect(x1, y1, x2, y2, color); + return; + } + + /* Brensenham line drawing algorithm */ + + int i, x = x1, y = y1, cumul; + int dx = x2 - x1, dy = y2 - y1; + int sx = sgn(dx), sy = sgn(dy); + + dx = abs(dx), dy = abs(dy); + + gpixel(x1, y1, color); + + if(dx >= dy) + { + /* Start with a non-zero cumul to even the overdue between the + two ends of the line (for more regularity) */ + cumul = dx >> 1; + for(i = 1; i < dx; i++) + { + x += sx; + cumul += dy; + if(cumul > dx) cumul -= dx, y += sy; + gpixel(x, y, color); + } + } + else + { + cumul = dy >> 1; + for(i = 1; i < dy; i++) + { + y += sy; + cumul += dx; + if(cumul > dy) cumul -= dy, x += sx; + gpixel(x, y, color); + } + } + + gpixel(x2, y2, color); +} diff --git a/src/gray/gpixel.c b/src/gray/gpixel.c new file mode 100644 index 0000000..87af2a4 --- /dev/null +++ b/src/gray/gpixel.c @@ -0,0 +1,59 @@ +#include +#include + +/* gpixel(): Change a pixel's color */ +void gpixel(int x, int y, color_t color) +{ + if((uint)x >= 128 || (uint)y >= 64) return; + + uint32_t *light, *dark; + gvram(&light, &dark); + + int offset = (y << 2) + (x >> 5); + uint32_t mask = 1 << (~x & 31), tmp; + + switch(color) + { + case C_WHITE: + light[offset] &= ~mask; + dark [offset] &= ~mask; + break; + + case C_LIGHT: + light[offset] |= mask; + dark [offset] &= ~mask; + break; + + case C_DARK: + light[offset] &= ~mask; + dark [offset] |= mask; + break; + + case C_BLACK: + light[offset] |= mask; + dark [offset] |= mask; + break; + + case C_NONE: + break; + + case C_INVERT: + light[offset] ^= mask; + dark [offset] ^= mask; + break; + + case C_LIGHTEN: + tmp = dark[offset]; + + dark[offset] &= light[offset] | ~mask; + light[offset] = (light[offset] ^ mask) & (tmp | ~mask); + break; + + case C_DARKEN: + tmp = dark[offset]; + + dark[offset] |= light[offset] & mask; + light[offset] = (light[offset] ^ mask) | (tmp & mask); + break; + } +} diff --git a/src/render/dline.c b/src/render/dline.c index 2a2c016..c9f9134 100644 --- a/src/render/dline.c +++ b/src/render/dline.c @@ -6,7 +6,7 @@ Remotely adapted from MonochromeLib code by Pierre "PerriotLL" Le Gall. Relies on platform-dependent dhline() and dvline() for optimized situations. @x1 @y1 @x2 @y2 Coordinates of endpoints of line (included) - @color Any R5G6B5 color */ + @color Any color accepted by dpixel() on the platform */ void dline(int x1, int y1, int x2, int y2, color_t color) { /* Possible optimizations */