1 /*
2 * OpenBOR - http://www.LavaLit.com
3 * -----------------------------------------------------------------------
4 * All rights reserved, see LICENSE in OpenBOR root for details.
5 *
6 * Copyright (c) 2004 - 2011 OpenBOR Team
7 */
8
9 // draw functions with 32bit pixel format, with alpha blending
10
11 #include <string.h>
12 #include "types.h"
13
14 #ifndef NULL
15 #define NULL ((void*)0)
16 #endif
17
18 #define abso(x) (x<0?-x:x)
19
20 #define __putpixel32(p) \
21 if(blendfp )\
22 {\
23 *(p) = blendfp(colour, *(p));\
24 }\
25 else\
26 {\
27 *(p) = colour;\
28 }
29
30 // same as the one in draw.c, this is 32bit version
31 // blendfp is the blending function pointer
line32(int sx,int sy,int ex,int ey,unsigned colour,s_screen * screen,int alpha)32 void line32(int sx, int sy, int ex, int ey, unsigned colour, s_screen *screen, int alpha)
33 {
34 int diffx, diffy;
35 int absdiffx, absdiffy;
36 int xdir, ydir;
37 int thres;
38 int d;
39 unsigned* data;
40 unsigned(*blendfp)(unsigned,unsigned);
41
42 // Some off-screen lines may slip through this test!
43 if(sx<0 && ex<0) return;
44 if(sy<0 && ey<0) return;
45 if(sx>=screen->width && ex>=screen->width) return;
46 if(sy>=screen->height && ey>=screen->height) return;
47
48
49 // Check clipping and calculate new coords if necessary
50
51 diffx = ex - sx;
52 diffy = ey - sy;
53
54 if(sx<0){
55 sy -= (sx*diffy/diffx);
56 sx = 0;
57 }
58 if(sy<0){
59 sx -= (sy*diffx/diffy);
60 sy = 0;
61 }
62 if(sx>=screen->width){
63 sy -= ((sx-screen->width)*diffy/diffx);
64 sx = screen->width-1;
65 }
66 if(sy>=screen->height){
67 sx -= ((sy-screen->height)*diffx/diffy);
68 sy = screen->height-1;
69 }
70
71 if(ex<0){
72 ey -= (ex*diffy/diffx);
73 ex = 0;
74 }
75 if(ey<0){
76 ex -= (ey*diffx/diffy);
77 ey = 0;
78 }
79 if(ex>=screen->width){
80 ey -= ((ex-screen->width)*diffy/diffx);
81 ex = screen->width-1;
82 }
83 if(ey>=screen->height){
84 ex -= ((ey-screen->height)*diffx/diffy);
85 ey = screen->height-1;
86 }
87
88
89 // Second test: the lines that passed test 1 won't pass this time!
90 if(sx<0 || ex<0) return;
91 if(sy<0 || ey<0) return;
92 if(sx>=screen->width || ex>=screen->width) return;
93 if(sy>=screen->height || ey>=screen->height) return;
94
95
96 // Recalculate directions
97 diffx = ex - sx;
98 diffy = ey - sy;
99
100 absdiffx = abso(diffx);
101 absdiffy = abso(diffy);
102
103 sy *= screen->width;
104 ey *= screen->width;
105
106 data = (unsigned*)screen->data;
107
108 colour &= 0x00FFFFFF;
109
110 blendfp = alpha>0?blendfunctions32[alpha-1]:NULL;
111
112 if(absdiffx > absdiffy)
113 {
114 // Draw a flat line
115 thres = absdiffx >> 1;
116 xdir = 1;
117 if(diffx<0) xdir = -xdir;
118 ydir = screen->width;
119 if(diffy<0) ydir = -ydir;
120 while(sx!=ex)
121 {
122 d = sx+sy;
123 __putpixel32(data+d);
124 sx += xdir;
125 if((thres-=absdiffy) <= 0){
126 sy += ydir;
127 thres += absdiffx;
128 }
129 }
130 d = ex+ey;
131 __putpixel32(data+d);
132 return;
133 }
134
135 // Draw a high line
136 thres = absdiffy >> 1;
137 xdir = 1;
138 if(diffx<0) xdir = -1;
139 ydir = screen->width;
140 if(diffy<0) ydir = -ydir;
141 while(sy!=ey){
142 d = sx+sy;
143 __putpixel32(data+d);
144 sy += ydir;
145 if((thres-=absdiffx) <= 0){
146 sx += xdir;
147 thres += absdiffy;
148 }
149 }
150 d = ex+ey;
151 __putpixel32(data+d);
152 }
153
154
155
156
157 // drawbox, 32bit version
drawbox32(int x,int y,int width,int height,unsigned colour,s_screen * screen,int alpha)158 void drawbox32(int x, int y, int width, int height, unsigned colour, s_screen *screen, int alpha)
159 {
160 unsigned *cp;
161 unsigned(*blendfp)(unsigned,unsigned);
162
163 if(width<=0) return;
164 if(height<=0) return;
165 if(screen==NULL) return;
166
167 if(x<0){
168 if((width+=x)<=0) return;
169 x = 0;
170 }
171 else if(x>=screen->width) return;
172 if(y<0){
173 if((height+=y)<=0) return;
174 y = 0;
175 }
176 else if(y>=screen->height) return;
177 if(x+width>screen->width) width = screen->width-x;
178 if(y+height>screen->height) height = screen->height-y;
179
180 cp = ((unsigned*)screen->data) + (y*screen->width + x);
181 colour &= 0x00FFFFFF;
182
183 blendfp = alpha>0?blendfunctions32[alpha-1]:NULL;
184
185 while(--height>=0){
186 for(x=0;x<width;x++){
187 __putpixel32(cp);
188 cp++;
189 }
190 cp += (screen->width - width);
191 }
192 }
193
194
195
196 // Putpixel 32bit version
putpixel32(unsigned x,unsigned y,unsigned colour,s_screen * screen,int alpha)197 void putpixel32(unsigned x, unsigned y, unsigned colour, s_screen *screen, int alpha){
198 int pixind;
199 unsigned* data ;
200 unsigned(*blendfp)(unsigned,unsigned);
201 if(x>screen->width || y>screen->height) return;
202 pixind = x+y*screen->width;
203 data = (unsigned*)screen->data + pixind;
204 colour &= 0x00FFFFFF;
205 blendfp = alpha>0?blendfunctions32[alpha-1]:NULL;
206 __putpixel32(data);
207 }
208
209
210