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