diff options
Diffstat (limited to 'engines/sci/gfx/gfx_support.cpp')
-rw-r--r-- | engines/sci/gfx/gfx_support.cpp | 48 |
1 files changed, 41 insertions, 7 deletions
diff --git a/engines/sci/gfx/gfx_support.cpp b/engines/sci/gfx/gfx_support.cpp index 2529fde35b..22de7055c2 100644 --- a/engines/sci/gfx/gfx_support.cpp +++ b/engines/sci/gfx/gfx_support.cpp @@ -34,15 +34,49 @@ namespace Sci { -static void drawProc(int x, int y, int c, void *data) { - gfx_pixmap_t *pxm = (gfx_pixmap_t *)data; - byte *p = pxm->index_data; - uint8 col = c; - memcpy(p + (y * pxm->index_width + x), &col, 1); -} +#define LINEMACRO(startx, starty, deltalinear, deltanonlinear, linearvar, nonlinearvar, \ + linearend, nonlinearstart, linearmod, nonlinearmod) \ + incrNE = ((deltalinear) > 0) ? (deltalinear) : -(deltalinear); \ + incrNE <<= 1; \ + deltanonlinear <<= 1; \ + incrE = ((deltanonlinear) > 0) ? -(deltanonlinear) : (deltanonlinear); \ + d = nonlinearstart - 1; \ + while (linearvar != (linearend)) { \ + memcpy(buffer + linewidth * (starty) + (startx), &color, pixelwidth); \ + linearvar += linearmod; \ + if ((d += incrE) < 0) { \ + d += incrNE; \ + nonlinearvar += nonlinearmod; \ + }; \ + }; \ + memcpy(buffer + linewidth * (starty) + (startx), &color, pixelwidth); + + +// Sierra's Bresenham line drawing +// WARNING: Do not just blindly replace this with Graphics::drawLine(), as it seems to create issues with flood fill +void gfx_draw_line_buffer(byte *buffer, int linewidth, int pixelwidth, Common::Point start, Common::Point end, unsigned int color) { + int incrE, incrNE, d; + int dx = ABS(end.x - start.x); + int dy = ABS(end.y - start.y); +#ifdef SCUMM_BIG_ENDIAN + color = SWAP_BYTES_32(color); +#endif + + if (dx > dy) { + int sign1 = (end.x < start.x) ? -1 : 1; + int sign2 = (end.y < start.y) ? -1 : 1; + LINEMACRO(start.x, start.y, dx, dy, start.x, start.y, end.x, dx, sign1 * pixelwidth, sign2); + } else { // dx <= dy + int sign1 = (end.y < start.y) ? -1 : 1; + int sign2 = (end.x < start.x) ? -1 : 1; + LINEMACRO(start.x, start.y, dy, dx, start.y, start.x, end.y, dy, sign1, sign2 * pixelwidth); + } + } + +#undef LINEMACRO void gfx_draw_line_pixmap_i(gfx_pixmap_t *pxm, Common::Point start, Common::Point end, int color) { - Graphics::drawLine(start.x, start.y, end.x, end.y, color, drawProc, pxm); + gfx_draw_line_buffer(pxm->index_data, pxm->index_width, 1, start, end, color); } void gfx_draw_box_buffer(byte *buffer, int linewidth, rect_t zone, int color) { |