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