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