1 /* Libvisual-plugins - Standard plugins for libvisual
2  *
3  * Copyright (C) 2000, 2001 Remi Arquier <arquier@crans.org>
4  *
5  * Authors: Remi Arquier <arquier@crans.org>
6  *	    Dennis Smit <ds@nerds-incorporated.org>
7  *
8  * $Id: draw_low_level.c,v 1.5 2005/12/20 18:49:12 synap Exp $
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as
12  * published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23  */
24 
25 #include <string.h>
26 #include <stdlib.h>
27 #include <math.h>
28 
29 #include "draw_low_level.h"
30 #include "jess.h"
31 
32 #define MAXE(a,b) ( (a) > (b) ? (b) : (a))
33 /*#define MAXE(a,b) (((int)(a>b))&1)*b+(((int)(!(a>b))&1)*a) */
34 #define MAX255(a) ((a<=255)*a+(!(a<=255))*255)
35 
tracer_point_add(JessPrivate * priv,uint8_t * buffer,int x,int y,uint8_t color)36 void tracer_point_add (JessPrivate *priv, uint8_t * buffer, int x, int y, uint8_t color)
37 {
38 	uint8_t *point;
39 	int calcul;
40 
41 	/*   goto non;  */
42 
43 	if (x >= priv->xres2 || x <= -priv->xres2 || y >= priv->yres2 || y <= -priv->yres2)
44 		return;
45 
46 	point = buffer + (-y + priv->yres2) * priv->resx + x + priv->xres2;
47 	calcul = (int)(color) + (int)(*point);
48 	*point = MAX255(calcul);
49 	/*  *point = MAXE ((int)color + *point, 255);
50 	*/
51 }
52 
tracer_point_add_32(JessPrivate * priv,uint8_t * buffer,int x,int y,uint8_t color)53 void tracer_point_add_32 (JessPrivate *priv, uint8_t * buffer, int x, int y, uint8_t color)
54 {
55 	uint8_t *point;
56 	int calcul;
57 
58 	if (x >= priv->xres2 || x <= -priv->xres2 || y >= priv->yres2 || y <= -priv->yres2)
59 		return;
60 
61 	point = buffer + (-y + priv->yres2) * priv->pitch + ((x + priv->xres2) << 2);
62 	/* *point = MAXE ((int)(color) + *point, 255); */
63 	calcul = (int)(color) + (int)(*point);
64 	*point = MAX255(calcul);
65 
66 	point++;
67 
68 	calcul = (int)(color) + (int)(*point);
69 	*point = MAX255(calcul);
70 
71 	/*  *point = MAXE ((int)color + *point, 255); */
72 	point++;
73 	calcul = (int)(color) + (int)(*point);
74 	*point = MAX255(calcul);
75 
76 	/*  *point = MAXE ((int)color + *point, 255); */
77 }
78 
cercle(JessPrivate * priv,uint8_t * buffer,int h,int k,int y,uint8_t color)79 void cercle (JessPrivate *priv, uint8_t * buffer, int h, int k, int y, uint8_t color)
80 {
81 	int x = -1, d = 3 - 2 * y;
82 
83 	while (x <= y)
84 	{
85 		if (d < 0)
86 		{
87 			d += 4 * x + 6;
88 			x++;
89 		}
90 		else
91 		{
92 			d += 4 * (x - y) + 10;
93 			x++;
94 			y--;
95 		}
96 		tracer_point_add (priv, buffer, h + x, y + k, color);
97 		tracer_point_add (priv, buffer, h + y, x + k, color);
98 		tracer_point_add (priv, buffer, h - y, x + k, color);
99 		tracer_point_add (priv, buffer, h - x, y + k, color);
100 		tracer_point_add (priv, buffer, h - x, -y + k, color);
101 		tracer_point_add (priv, buffer, h - y, -x + k, color);
102 		tracer_point_add (priv, buffer, h + y, -x + k, color);
103 		tracer_point_add (priv, buffer, h + x, -y + k, color);
104 	}
105 }
106 
cercle_32(JessPrivate * priv,uint8_t * buffer,int h,int k,int y,uint8_t color)107 void cercle_32 (JessPrivate *priv, uint8_t * buffer, int h, int k, int y, uint8_t color)
108 {
109 	int x = -1, d = 3 - 2 * y;
110 
111 	while (x <= y)
112 	{
113 		if (d < 0)
114 		{
115 			d += 2* x+6 ;
116 			x++;
117 		}
118 		else
119 		{
120 			d += 4 * (x - y)+10 ;
121 			x++;
122 			y--;
123 		}
124 		tracer_point_add_32 (priv, buffer, h + x, y + k, color);
125 		tracer_point_add_32 (priv, buffer, h + y, x + k, color);
126 		tracer_point_add_32 (priv, buffer, h - y, x + k, color);
127 		tracer_point_add_32 (priv, buffer, h - x, y + k, color);
128 		tracer_point_add_32 (priv, buffer, h - x, -y + k, color);
129 		tracer_point_add_32 (priv, buffer, h - y, -x + k, color);
130 		tracer_point_add_32 (priv, buffer, h + y, -x + k, color);
131 		tracer_point_add_32 (priv, buffer, h + x, -y + k, color);
132 	}
133 }
134 
boule_random(JessPrivate * priv,uint8_t * buffer,int x,int y,int r,uint8_t color)135 void boule_random (JessPrivate *priv, uint8_t * buffer, int x, int y, int r, uint8_t color)
136 {
137 	int i, j, ecart = (int) visual_random_context_int(priv->rcontext)%5+1;
138 	j = color;
139 	if (priv->video == 8)
140 	{
141 		for (i = 0; i <= r; i+=ecart)
142 		{
143 
144 			cercle (priv, buffer, x, y, i, (int) ((float) (j * j) / (256)));
145 			j = color - color * ((float) i) / r;
146 		}
147 	}
148 	else
149 	{
150 		for (i = 0; i <= r; i+=ecart)
151 		{
152 
153 			cercle_32 (priv, buffer, x, y, i, (int) ((float) (j * j) / (256)));
154 			j = color - color * ((float) i) / r;
155 		}
156 	}
157 }
158 
boule(JessPrivate * priv,uint8_t * buffer,int x,int y,int r,uint8_t color)159 void boule (JessPrivate *priv, uint8_t * buffer, int x, int y, int r, uint8_t color)
160 {
161 	int i, j;
162 
163 	if (priv->video == 8)
164 	{
165 		for (i = r; i >= 0; i--)
166 		{
167 			j = color - color * ((float) i) / r;
168 			/*	cercle (buffer, x, y, i, (int) ((float) (j * j) / (256))); */
169 			/* Optimisation by Karl Soulabaille.
170 			   Remplace un flottant par un entier */
171 			cercle (priv, buffer, x, y, i, (j*j)>>8);
172 		}
173 
174 	}
175 	else
176 	{
177 		for (i = 0; i < r; i++)
178 		{
179 			j = color - color * ((float) i) / r;
180 			/*	cercle_32 (buffer, x, y, i, (int) ((float) (j * j) / (256))); */
181 			cercle_32 (priv, buffer, x, y, i, (j*j)>>8);
182 		}
183 	}
184 }
185 
droite(JessPrivate * priv,uint8_t * buffer,int x1,int y1,int x2,int y2,uint8_t color)186 void droite (JessPrivate *priv, uint8_t * buffer, int x1, int y1, int x2, int y2, uint8_t color)
187 {
188 
189 	int lx, ly, dx, dy;
190 	int i, j, k;
191 
192 	lx = abs(x1-x2);
193 	ly = abs(y1-y2);
194 	dx = (x1>x2) ? -1 : 1;
195 	dy = (y1>y2) ? -1 : 1;
196 
197 	if (priv->video == 8)
198 	{
199 		if (lx>ly)
200 		{
201 			for (i=x1,j=y1,k=0;i!=x2;i+=dx,k+=ly)
202 			{
203 				if (k>=lx)
204 				{
205 					k -= lx;
206 					j += dy;
207 				}
208 				tracer_point_add (priv, buffer, i, j, color);
209 			}
210 		}
211 		else
212 		{
213 			for (i=y1,j=x1,k=0;i!=y2;i+=dy,k+=lx)
214 			{
215 				if (k>=ly)
216 				{
217 					k -= ly;
218 					j += dx;
219 				}
220 				tracer_point_add (priv, buffer, j, i, color);
221 			}
222 		}
223 	}
224 	else
225 	{
226 		if (lx>ly)
227 		{
228 			for (i=x1,j=y1,k=0;i!=x2;i+=dx,k+=ly)
229 			{
230 				if (k>=lx)
231 				{
232 					k -= lx;
233 					j += dy;
234 				}
235 				tracer_point_add_32 (priv, buffer, i, j, color);
236 			}
237 		}
238 		else
239 		{
240 			for (i=y1,j=x1,k=0;i!=y2;i+=dy,k+=lx)
241 			{
242 				if (k>=ly)
243 				{
244 					k -= ly;
245 					j += dx;
246 				}
247 				tracer_point_add_32 (priv, buffer, j, i, color);
248 			}
249 		}
250 	}
251 }
252 
ball_init(JessPrivate * priv)253 void ball_init(JessPrivate *priv)
254 {
255 	int i,j,k;
256 	int x,y;
257 	int ssize;
258 
259 	if (priv->big_ball != NULL)
260 		visual_mem_free (priv->big_ball);
261 
262 	ssize = BIG_BALL_SIZE * BIG_BALL_SIZE;
263 	priv->big_ball = (uint8_t *) visual_mem_malloc0(ssize);
264 
265 	for (i=0 ; i < BIG_BALL_SIZE ;i++)
266 	{
267 		if (priv->big_ball_scale[i] != NULL)
268 			visual_mem_free (priv->big_ball_scale[i]);
269 
270 		ssize = (i + 1) * sizeof (int);
271 		priv->big_ball_scale[i] = (uint32_t *) visual_mem_malloc0(ssize);
272 	}
273 
274 	for (i=0 ; i < BIG_BALL_SIZE ;i++)
275 		for (j=0 ; j<i ;j++)
276 			priv->big_ball_scale[i][j] = (int) floor((float)j*BIG_BALL_SIZE/(i+1));
277 
278 	/*creation de la grande boulle */
279 	for (i =0; i< BIG_BALL_SIZE/2; i++) /*pour chaque rayon*/
280 	{
281 		for (j=0; j< 2000; j++)
282 		{
283 			x = (int) ((float) (BIG_BALL_SIZE/2 + i*0.5*cos((float)j/2000*2*3.1416)) );
284 			y = (int) ((float) (BIG_BALL_SIZE/2 + i*0.5*sin((float)j/2000*2*3.1416)) );
285 
286 			k = 255-255 * ((float) (i) / (BIG_BALL_SIZE/2));
287 
288 			priv->big_ball[ y * BIG_BALL_SIZE + x] = MAX255(3*((k*k)>>9));
289 		}
290 	}
291 }
292 
ball(JessPrivate * priv,uint8_t * buffer,int x,int y,int r,uint8_t color)293 void ball(JessPrivate *priv, uint8_t *buffer, int x, int y, int r, uint8_t color)
294 {
295 	int i,j,k,d= 2*r;
296 	int *pt=priv->big_ball_scale[d],colorc;
297 	float fcolor = (float) color;
298 
299 	int a,b,c,e,f,g,h,l;
300 	if (d>=BIG_BALL_SIZE)
301 		r = BIG_BALL_SIZE/ 2 - 1;
302 
303 	if (priv->video == 8)
304 	{
305 		for (j=-r+1; j <= 0; j++)
306 		{
307 			k = pt[j+r-1] * BIG_BALL_SIZE;
308 			a = j + y;
309 			b = j + x ;
310 			c = -j + x ;
311 			e = -j + y  ;
312 			for (i=-r+1; i <= j; i++)
313 			{
314 				f = i + x ;
315 				g = -i + x;
316 				h = i + y;
317 				l = -i + y;
318 
319 				colorc = (int) (fcolor/256* (float) priv->big_ball[k + pt[i+r-1]]);
320 
321 				tracer_point_add(priv, buffer, f   ,a        ,	colorc );
322 				tracer_point_add(priv, buffer, g     ,a        ,	colorc );
323 				tracer_point_add(priv, buffer, f     ,e        ,	colorc );
324 				tracer_point_add(priv, buffer, g     ,e        ,	colorc );
325 
326 				tracer_point_add(priv, buffer, b         ,h     ,	colorc );
327 				tracer_point_add(priv, buffer, b         ,l     , 	colorc );
328 				tracer_point_add(priv, buffer, c         ,h     ,	colorc );
329 				tracer_point_add(priv, buffer, c         ,l     ,	colorc );
330 			}
331 		}
332 	}
333 	else
334 	{
335 		for (j=-r+1; j <= 0; j++)
336 		{
337 			k = pt[j+r-1] * BIG_BALL_SIZE;
338 			a = j + y;
339 			b = j + x ;
340 			c = -j + x ;
341 			e = -j + y  ;
342 			for (i=-r+1; i <= j; i++)
343 			{
344 				f = i + x ;
345 				g = -i + x;
346 				h = i + y;
347 				l = -i + y;
348 
349 				colorc = (int) (fcolor/256* (float)priv->big_ball[k + pt[i+r-1]]);
350 
351 				tracer_point_add_32 (priv, buffer, f   ,a        ,	colorc );
352 				tracer_point_add_32 (priv, buffer, g     ,a        ,	colorc );
353 				tracer_point_add_32 (priv, buffer, f     ,e        ,	colorc );
354 				tracer_point_add_32 (priv, buffer, g     ,e        ,	colorc );
355 
356 				tracer_point_add_32 (priv, buffer, b         ,h     ,	colorc );
357 				tracer_point_add_32 (priv, buffer, b         ,l     , 	colorc );
358 				tracer_point_add_32 (priv, buffer, c         ,h     ,	colorc );
359 				tracer_point_add_32 (priv, buffer, c         ,l     ,	colorc );
360 			}
361 		}
362 	}
363 }
364 
365 void
boule_no_add(uint8_t * buffer,int x,int y,int r,uint8_t color)366 boule_no_add (uint8_t * buffer, int x, int y, int r, uint8_t color)
367 {
368 	int i, j;
369 	for (i = r; i >= 0; i--)
370 	{
371 		j = color - color * ((float) i) / r;
372 		cercle_no_add (buffer, x, y, i, (j*j)>>8);
373 	}
374 }
375 
cercle_no_add(uint8_t * buffer,int h,int k,int y,uint8_t color)376 void cercle_no_add (uint8_t * buffer, int h, int k, int y, uint8_t color)
377 {
378 	int x = -1, d = 3 - 2 * y;
379 
380 	while (x <= y)
381 	{
382 		if (d < 0)
383 		{
384 			d += 4 * x + 6;
385 			x++;
386 		}
387 		else
388 		{
389 			d += 4 * (x - y) + 10;
390 			x++;
391 			y--;
392 		}
393 		tracer_point_no_add (buffer, h + x, y + k, color);
394 		tracer_point_no_add (buffer, h + y, x + k, color);
395 		tracer_point_no_add (buffer, h - y, x + k, color);
396 		tracer_point_no_add (buffer, h - x, y + k, color);
397 		tracer_point_no_add (buffer, h - x, -y + k, color);
398 		tracer_point_no_add (buffer, h - y, -x + k, color);
399 		tracer_point_no_add (buffer, h + y, -x + k, color);
400 		tracer_point_no_add (buffer, h + x, -y + k, color);
401 	}
402 }
403 
tracer_point_no_add(uint8_t * buffer,int x,int y,uint8_t color)404 void tracer_point_no_add (uint8_t * buffer, int x, int y, uint8_t color)
405 {
406 	uint8_t *point;
407 
408 	point = buffer + (-y + BIG_BALL_SIZE/2) * BIG_BALL_SIZE + x + BIG_BALL_SIZE/2;
409 	*point = (int)(color);
410 }
411 
412