• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Goom Project
2  * Copyright (C) <2003> iOS-Software
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19 #include "drawmethods.h"
20 
21 #define DRAWMETHOD_PLUS(_out,_backbuf,_col) \
22 {\
23       int tra=0,i=0;\
24       unsigned char *bra = (unsigned char*)&(_backbuf);\
25       unsigned char *dra = (unsigned char*)&(_out);\
26       unsigned char *cra = (unsigned char*)&(_col);\
27       for (;i<4;i++) {\
28 				tra = *cra;\
29 				tra += *bra;\
30 				if (tra>255) tra=255;\
31 				*dra = tra;\
32 				++dra;++cra;++bra;\
33 			}\
34 }
35 
36 #define DRAWMETHOD DRAWMETHOD_PLUS(*p,*p,col)
37 
38 void
draw_line(Pixel * data,int x1,int y1,int x2,int y2,int col,int screenx,int screeny)39 draw_line (Pixel * data, int x1, int y1, int x2, int y2, int col, int screenx,
40     int screeny)
41 {
42   int x, y, dx, dy, yy, xx;
43   Pixel *p;
44 
45   if ((y1 < 0) || (y2 < 0) || (x1 < 0) || (x2 < 0) || (y1 >= screeny)
46       || (y2 >= screeny) || (x1 >= screenx) || (x2 >= screenx))
47     return;
48 
49   /* clip to top edge
50      if ((y1 < 0) && (y2 < 0))
51      return;
52 
53      if (y1 < 0) {
54      x1 += (y1 * (x1 - x2)) / (y2 - y1);
55      y1 = 0;
56      }
57      if (y2 < 0) {
58      x2 += (y2 * (x1 - x2)) / (y2 - y1);
59      y2 = 0;
60      }
61 
62      clip to bottom edge
63      if ((y1 >= screeny) && (y2 >= screeny))
64      return;
65      if (y1 >= screeny) {
66      x1 -= ((screeny - y1) * (x1 - x2)) / (y2 - y1);
67      y1 = screeny - 1;
68      }
69      if (y2 >= screeny) {
70      x2 -= ((screeny - y2) * (x1 - x2)) / (y2 - y1);
71      y2 = screeny - 1;
72      }
73      clip to left edge
74      if ((x1 < 0) && (x2 < 0))
75      return;
76      if (x1 < 0) {
77      y1 += (x1 * (y1 - y2)) / (x2 - x1);
78      x1 = 0;
79      }
80      if (x2 < 0) {
81      y2 += (x2 * (y1 - y2)) / (x2 - x1);
82      x2 = 0;
83      }
84      clip to right edge
85      if ((x1 >= screenx) && (x2 >= screenx))
86      return;
87      if (x1 >= screenx) {
88      y1 -= ((screenx - x1) * (y1 - y2)) / (x2 - x1);
89      x1 = screenx - 1;
90      }
91      if (x2 >= screenx) {
92      y2 -= ((screenx - x2) * (y1 - y2)) / (x2 - x1);
93      x2 = screenx - 1;
94      }
95    */
96 
97   dx = x2 - x1;
98   dy = y2 - y1;
99   if (x1 > x2) {
100     int tmp;
101 
102     tmp = x1;
103     x1 = x2;
104     x2 = tmp;
105     tmp = y1;
106     y1 = y2;
107     y2 = tmp;
108     dx = x2 - x1;
109     dy = y2 - y1;
110   }
111 
112   /* vertical line */
113   if (dx == 0) {
114     if (y1 < y2) {
115       p = &(data[(screenx * y1) + x1]);
116       for (y = y1; y <= y2; y++) {
117         DRAWMETHOD;
118         p += screenx;
119       }
120     } else {
121       p = &(data[(screenx * y2) + x1]);
122       for (y = y2; y <= y1; y++) {
123         DRAWMETHOD;
124         p += screenx;
125       }
126     }
127     return;
128   }
129   /* horizontal line */
130   if (dy == 0) {
131     if (x1 < x2) {
132       p = &(data[(screenx * y1) + x1]);
133       for (x = x1; x <= x2; x++) {
134         DRAWMETHOD;
135         p++;
136       }
137       return;
138     } else {
139       p = &(data[(screenx * y1) + x2]);
140       for (x = x2; x <= x1; x++) {
141         DRAWMETHOD;
142         p++;
143       }
144       return;
145     }
146   }
147   /* 1    */
148   /* \   */
149   /* \  */
150   /* 2 */
151   if (y2 > y1) {
152     /* steep */
153     if (dy > dx) {
154       dx = ((dx << 16) / dy);
155       x = x1 << 16;
156       for (y = y1; y <= y2; y++) {
157         xx = x >> 16;
158         p = &(data[(screenx * y) + xx]);
159         DRAWMETHOD;
160         if (xx < (screenx - 1)) {
161           p++;
162           /* DRAWMETHOD; */
163         }
164         x += dx;
165       }
166       return;
167     }
168     /* shallow */
169     else {
170       dy = ((dy << 16) / dx);
171       y = y1 << 16;
172       for (x = x1; x <= x2; x++) {
173         yy = y >> 16;
174         p = &(data[(screenx * yy) + x]);
175         DRAWMETHOD;
176         if (yy < (screeny - 1)) {
177           p += screeny;
178           /* DRAWMETHOD; */
179         }
180         y += dy;
181       }
182     }
183   }
184   /* 2 */
185   /* /  */
186   /* /   */
187   /* 1    */
188   else {
189     /* steep */
190     if (-dy > dx) {
191       dx = ((dx << 16) / -dy);
192       x = (x1 + 1) << 16;
193       for (y = y1; y >= y2; y--) {
194         xx = x >> 16;
195         p = &(data[(screenx * y) + xx]);
196         DRAWMETHOD;
197         if (xx < (screenx - 1)) {
198           p--;
199           /* DRAWMETHOD; */
200         }
201         x += dx;
202       }
203       return;
204     }
205     /* shallow */
206     else {
207       dy = ((dy << 16) / dx);
208       y = y1 << 16;
209       for (x = x1; x <= x2; x++) {
210         yy = y >> 16;
211         p = &(data[(screenx * yy) + x]);
212         DRAWMETHOD;
213         if (yy < (screeny - 1)) {
214           p += screeny;
215           /* DRAWMETHOD; */
216         }
217         y += dy;
218       }
219       return;
220     }
221   }
222 }
223