4 * This file is part of OpenTTD.
5 * 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.
6 * 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.
7 * 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/>.
10 /** @file base.cpp Implementation of the base for all blitters. */
12 #include "../stdafx.h"
14 #include "../core/math_func.hpp"
16 #include "../safeguards.h"
18 void Blitter::DrawLine(void *video
, int x
, int y
, int x2
, int y2
, int screen_width
, int screen_height
, uint8 colour
, int width
, int dash
)
41 if (dx
== 0 && dy
== 0) {
42 /* The algorithm below cannot handle this special case; make it work at least for line width 1 */
43 if (x
>= 0 && x
< screen_width
&& y
>= 0 && y
< screen_height
) this->SetPixel(video
, x
, y
, colour
);
47 int frac_diff
= width
* max(dx
, dy
);
49 /* compute frac_diff = width * sqrt(dx*dx + dy*dy)
51 * max(dx, dy) <= sqrt(dx*dx + dy*dy) <= sqrt(2) * max(dx, dy) <= 3/2 * max(dx, dy) */
52 int frac_sq
= width
* width
* (dx
* dx
+ dy
* dy
);
53 int frac_max
= 3 * frac_diff
/ 2;
54 while (frac_diff
< frac_max
) {
55 int frac_test
= (frac_diff
+ frac_max
) / 2;
56 if (frac_test
* frac_test
< frac_sq
) {
57 frac_diff
= frac_test
+ 1;
59 frac_max
= frac_test
- 1;
65 if (dash
== 0) dash
= 1;
70 int frac_low
= dy
- frac_diff
/ 2;
71 int frac_high
= dy
+ frac_diff
/ 2;
73 while (frac_low
+ dx
/ 2 < 0) {
77 while (frac_high
- dx
/ 2 >= 0) {
84 if (dash_count
< dash
&& x
>= 0 && x
< screen_width
) {
85 for (int y
= y_low
; y
!= y_high
; y
+= stepy
) {
86 if (y
>= 0 && y
< screen_height
) this->SetPixel(video
, x
, y
, colour
);
100 if (++dash_count
>= dash
+ gap
) dash_count
= 0;
105 int frac_low
= dx
- frac_diff
/ 2;
106 int frac_high
= dx
+ frac_diff
/ 2;
108 while (frac_low
+ dy
/ 2 < 0) {
112 while (frac_high
- dy
/ 2 >= 0) {
119 if (dash_count
< dash
&& y
>= 0 && y
< screen_height
) {
120 for (int x
= x_low
; x
!= x_high
; x
+= stepx
) {
121 if (x
>= 0 && x
< screen_width
) this->SetPixel(video
, x
, y
, colour
);
128 if (frac_high
>= 0) {
135 if (++dash_count
>= dash
+ gap
) dash_count
= 0;