base.cpp

Go to the documentation of this file.
00001 /* $Id$ */
00002 
00003 /*
00004  * This file is part of OpenTTD.
00005  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
00006  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00007  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
00008  */
00009 
00012 #include "../stdafx.h"
00013 #include "base.hpp"
00014 #include "../core/math_func.hpp"
00015 
00016 void Blitter::DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8 colour, int width)
00017 {
00018   int dy;
00019   int dx;
00020   int stepx;
00021   int stepy;
00022 
00023   dy = (y2 - y) * 2;
00024   if (dy < 0) {
00025     dy = -dy;
00026     stepy = -1;
00027   } else {
00028     stepy = 1;
00029   }
00030 
00031   dx = (x2 - x) * 2;
00032   if (dx < 0) {
00033     dx = -dx;
00034     stepx = -1;
00035   } else {
00036     stepx = 1;
00037   }
00038 
00039   int frac_diff = width * max(dx, dy);
00040   if (width > 1) {
00041     /* compute frac_diff = width * sqrt(dx*dx + dy*dy)
00042      * Start interval:
00043      *    max(dx, dy) <= sqrt(dx*dx + dy*dy) <= sqrt(2) * max(dx, dy) <= 3/2 * max(dx, dy) */
00044     int frac_sq = width * width * (dx * dx + dy * dy);
00045     int frac_max = 3 * frac_diff / 2;
00046     while (frac_diff < frac_max) {
00047       int frac_test = (frac_diff + frac_max) / 2;
00048       if (frac_test * frac_test < frac_sq) {
00049         frac_diff = frac_test + 1;
00050       } else {
00051         frac_max = frac_test - 1;
00052       }
00053     }
00054   }
00055 
00056   if (dx > dy) {
00057     int y_low     = y;
00058     int y_high    = y;
00059     int frac_low  = dy - frac_diff / 2;
00060     int frac_high = dy + frac_diff / 2;
00061 
00062     while (frac_low + dx / 2 < 0) {
00063       frac_low += dx;
00064       y_low -= stepy;
00065     }
00066     while (frac_high - dx / 2 >= 0) {
00067       frac_high -= dx;
00068       y_high += stepy;
00069     }
00070     x2 += stepx;
00071 
00072     while (x != x2) {
00073       if (x >= 0 && x < screen_width) {
00074         for (int y = y_low; y != y_high; y += stepy) {
00075           if (y >= 0 && y < screen_height) this->SetPixel(video, x, y, colour);
00076         }
00077       }
00078       if (frac_low >= 0) {
00079         y_low += stepy;
00080         frac_low -= dx;
00081       }
00082       if (frac_high >= 0) {
00083         y_high += stepy;
00084         frac_high -= dx;
00085       }
00086       x += stepx;
00087       frac_low += dy;
00088       frac_high += dy;
00089     }
00090   } else {
00091     int x_low     = x;
00092     int x_high    = x;
00093     int frac_low  = dx - frac_diff / 2;
00094     int frac_high = dx + frac_diff / 2;
00095 
00096     while (frac_low + dy / 2 < 0) {
00097       frac_low += dy;
00098       x_low -= stepx;
00099     }
00100     while (frac_high - dy / 2 >= 0) {
00101       frac_high -= dy;
00102       x_high += stepx;
00103     }
00104     y2 += stepy;
00105 
00106     while (y != y2) {
00107       if (y >= 0 && y < screen_height) {
00108         for (int x = x_low; x != x_high; x += stepx) {
00109           if (x >= 0 && x < screen_width) this->SetPixel(video, x, y, colour);
00110         }
00111       }
00112       if (frac_low >= 0) {
00113         x_low += stepx;
00114         frac_low -= dy;
00115       }
00116       if (frac_high >= 0) {
00117         x_high += stepx;
00118         frac_high -= dy;
00119       }
00120       y += stepy;
00121       frac_low += dx;
00122       frac_high += dx;
00123     }
00124   }
00125 }

Generated on Sun May 8 07:30:10 2011 for OpenTTD by  doxygen 1.6.1