aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTorbjörn Andersson2005-04-20 14:45:23 +0000
committerTorbjörn Andersson2005-04-20 14:45:23 +0000
commita18d4d5c2f6dbc985c5b3628228bb6078cf781bb (patch)
tree052500a3f8e5f53429adba3f5eea50da35130d0d
parent8b559ff87527f1b01a4358edbcbb7d90ec93764b (diff)
downloadscummvm-rg350-a18d4d5c2f6dbc985c5b3628228bb6078cf781bb.tar.gz
scummvm-rg350-a18d4d5c2f6dbc985c5b3628228bb6078cf781bb.tar.bz2
scummvm-rg350-a18d4d5c2f6dbc985c5b3628228bb6078cf781bb.zip
Replaced drawLine() with a shorter version described in Wikipedia. It uses
a callback to plot each point so that it doesn't need to worry about how the caller deals with screen dirtying, etc. My plan is to move this function into a standard class. (That's why I used the American spelling "color" instead of "colour".) I just haven't made up my mind on which is the most appropriate one yet. svn-id: r17715
-rw-r--r--sword2/build_display.h5
-rw-r--r--sword2/driver/render.cpp171
2 files changed, 43 insertions, 133 deletions
diff --git a/sword2/build_display.h b/sword2/build_display.h
index bccd88ad87..11b25e6694 100644
--- a/sword2/build_display.h
+++ b/sword2/build_display.h
@@ -415,8 +415,9 @@ public:
void buildDisplay();
- void plotPoint(int16 x, int16 y, uint8 colour);
- void drawLine(int16 x1, int16 y1, int16 x2, int16 y2, uint8 colour);
+ void plotPoint(int x, int y, uint8 colour);
+ void drawLine(int x0, int y0, int x1, int y1, uint8 colour);
+ void drawLine(int x0, int y0, int x1, int y1, int color, void (*plotProc)(int, int, int, void *), void *data);
#ifdef BACKEND_8BIT
void plotYUV(byte *lut, int width, int height, byte *const *dat);
diff --git a/sword2/driver/render.cpp b/sword2/driver/render.cpp
index 8587be3b36..0cb20b0291 100644
--- a/sword2/driver/render.cpp
+++ b/sword2/driver/render.cpp
@@ -198,7 +198,7 @@ void Screen::scaleImageGood(byte *dst, uint16 dstPitch, uint16 dstWidth, uint16
* @param colour colour of the point
*/
-void Screen::plotPoint(int16 x, int16 y, uint8 colour) {
+void Screen::plotPoint(int x, int y, uint8 colour) {
byte *buf = _buffer + MENUDEEP * RENDERWIDE;
x -= _scrollX;
@@ -210,6 +210,11 @@ void Screen::plotPoint(int16 x, int16 y, uint8 colour) {
}
}
+static void plot(int x, int y, int colour, void *data) {
+ Screen *screen = (Screen *) data;
+ screen->plotPoint(x, y, (uint8) colour);
+}
+
/**
* Draws a line from one point to another. This is only used for debugging.
* @param x0 x-coordinate of the start point
@@ -219,144 +224,48 @@ void Screen::plotPoint(int16 x, int16 y, uint8 colour) {
* @param colour colour of the line
*/
-// Uses Bresenham's incremental algorithm!
+void Screen::drawLine(int x0, int y0, int x1, int y1, uint8 colour) {
+ drawLine(x0, y0, x1, y1, colour, &plot, this);
+}
-void Screen::drawLine(int16 x0, int16 y0, int16 x1, int16 y1, uint8 colour) {
- int dxmod, dymod;
- int ince, incne;
- int d;
- int x, y;
- int addTo;
+// TODO: Main line-drawing function. Move this somewhere where other engines
+// can benefit from it.
- // Make sure we're going from left to right
+void Screen::drawLine(int x0, int y0, int x1, int y1, int color, void (*plotProc)(int, int, int, void *), void *data) {
+ // Bresenham's line algorithm, as described by Wikipedia
+ bool steep = ABS(y1 - y0) > ABS(x1 - x0);
- if (x1 < x0) {
- SWAP(x0, x1);
- SWAP(y0, y1);
+ if (steep) {
+ SWAP(x0, y0);
+ SWAP(x1, y1);
}
- int dx = x1 - x0;
- int dy = y1 - y0;
-
- if (dx < 0)
- dxmod = -dx;
- else
- dxmod = dx;
+ int delta_x = ABS(x1 - x0);
+ int delta_y = ABS(y1 - y0);
+ int err = 0;
+ int delta_err = delta_y;
+ int x = x0;
+ int y = y0;
- if (dy < 0)
- dymod = -dy;
- else
- dymod = dy;
-
- if (dxmod >= dymod) {
- if (dy > 0) {
- d = 2 * dy - dx;
- ince = 2 * dy;
- incne = 2 * (dy - dx);
- x = x0;
- y = y0;
-
- plotPoint(x, y, colour);
-
- while (x < x1) {
- if (d <= 0) {
- d += ince;
- x++;
- } else {
- d += incne;
- x++;
- y++;
- }
+ int x_step = (x0 < x1) ? 1 : -1;
+ int y_step = (y0 < y1) ? 1 : -1;
- plotPoint(x, y, colour);
- }
- } else {
- addTo = y0;
- y0 = 0;
- y1 -= addTo;
- y1 = -y1;
- dy = y1 - y0;
-
- d = 2 * dy - dx;
- ince = 2 * dy;
- incne = 2 * (dy - dx);
- x = x0;
- y = y0;
-
- plotPoint(x, addTo - y, colour);
-
- while (x < x1) {
- if (d <= 0) {
- d += ince;
- x++;
- } else {
- d += incne;
- x++;
- y++;
- }
-
- plotPoint(x, addTo - y, colour);
- }
- }
- } else {
- // OK, y is now going to be the single increment.
- // Ensure the line is going top to bottom
- if (y1 < y0) {
- SWAP(x0, x1);
- SWAP(y0, y1);
- }
- dx = x1 - x0;
- dy = y1 - y0;
-
- if (dx > 0) {
- d = 2 * dx - dy;
- ince = 2 * dx;
- incne = 2 * (dx - dy);
- x = x0;
- y = y0;
-
- plotPoint(x, y, colour);
-
- while (y < y1) {
- if (d <= 0) {
- d += ince;
- y++;
- } else {
- d += incne;
- x++;
- y++;
- }
-
- plotPoint(x, y, colour);
- }
- } else {
- addTo = x0;
- x0 = 0;
- x1 -= addTo;
- x1 = -x1;
- dx = x1 - x0;
-
- d = 2 * dx - dy;
- ince = 2 * dx;
- incne = 2 * (dx - dy);
- x = x0;
- y = y0;
-
- plotPoint(addTo - x, y, colour);
-
- while (y < y1) {
- if (d <= 0) {
- d += ince;
- y++;
- } else {
- d += incne;
- x++;
- y++;
- }
-
- plotPoint(addTo - x, y, colour);
- }
+ if (steep)
+ (*plotProc)(y, x, color, data);
+ else
+ (*plotProc)(x, y, color, data);
+
+ while (x != x1) {
+ x += x_step;
+ err += delta_err;
+ if (2 * err > delta_x) {
+ y += y_step;
+ err -= delta_x;
}
+ if (steep)
+ (*plotProc)(y, x, color, data);
+ else
+ (*plotProc)(x, y, color, data);
}
}