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 
20 #include "lines.h"
21 #include <math.h>
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include "goom_tools.h"
25 #include "drawmethods.h"
26 #include "goom_plugin_info.h"
27 
28 static inline unsigned char
lighten(unsigned char value,float power)29 lighten (unsigned char value, float power)
30 {
31   int val = value;
32   float t = (float) val * log10 (power) / 2.0;
33 
34   if (t > 0) {
35     val = (int) t;              /* (32.0f * log (t)); */
36     if (val > 255)
37       val = 255;
38     if (val < 0)
39       val = 0;
40     return val;
41   } else {
42     return 0;
43   }
44 }
45 
46 static void
lightencolor(guint32 * col,float power)47 lightencolor (guint32 * col, float power)
48 {
49   unsigned char *color;
50 
51   color = (unsigned char *) col;
52   *color = lighten (*color, power);
53   color++;
54   *color = lighten (*color, power);
55   color++;
56   *color = lighten (*color, power);
57   color++;
58   *color = lighten (*color, power);
59 }
60 
61 
62 
63 static void
genline(int id,float param,GMUnitPointer * l,int rx,int ry)64 genline (int id, float param, GMUnitPointer * l, int rx, int ry)
65 {
66   int i;
67 
68   switch (id) {
69     case GML_HLINE:
70       for (i = 0; i < 512; i++) {
71         l[i].x = ((float) i * rx) / 512.0f;
72         l[i].y = param;
73         l[i].angle = G_PI / 2.0f;
74       }
75       return;
76     case GML_VLINE:
77       for (i = 0; i < 512; i++) {
78         l[i].y = ((float) i * ry) / 512.0f;
79         l[i].x = param;
80         l[i].angle = 0.0f;
81       }
82       return;
83     case GML_CIRCLE:
84       for (i = 0; i < 512; i++) {
85         float cosa, sina;
86 
87         l[i].angle = 2.0f * G_PI * (float) i / 512.0f;
88         cosa = param * cos (l[i].angle);
89         sina = param * sin (l[i].angle);
90         l[i].x = ((float) rx / 2.0f) + cosa;
91         l[i].y = (float) ry / 2.0f + sina;
92       }
93       return;
94   }
95 }
96 
97 static guint32
getcouleur(int mode)98 getcouleur (int mode)
99 {
100   switch (mode) {
101     case GML_RED:
102       return (230 << (ROUGE * 8)) | (120 << (VERT * 8)) | (18 << (BLEU * 8));
103     case GML_ORANGE_J:
104       return (120 << (VERT * 8)) | (252 << (ROUGE * 8)) | (18 << (BLEU * 8));
105     case GML_ORANGE_V:
106       return (160 << (VERT * 8)) | (236 << (ROUGE * 8)) | (40 << (BLEU * 8));
107     case GML_BLEUBLANC:
108       return (40 << (BLEU * 8)) | (220 << (ROUGE * 8)) | (140 << (VERT * 8));
109     case GML_VERT:
110       return (200 << (VERT * 8)) | (80 << (ROUGE * 8)) | (18 << (BLEU * 8));
111     case GML_BLEU:
112       return (250 << (BLEU * 8)) | (30 << (VERT * 8)) | (80 << (ROUGE * 8));
113     case GML_BLACK:
114       return (16 << (BLEU * 8)) | (16 << (VERT * 8)) | (16 << (ROUGE * 8));
115   }
116   return 0;
117 }
118 
119 void
goom_lines_set_res(GMLine * gml,int rx,int ry)120 goom_lines_set_res (GMLine * gml, int rx, int ry)
121 {
122   if (gml != NULL) {
123     gml->screenX = rx;
124     gml->screenY = ry;
125 
126     genline (gml->IDdest, gml->param, gml->points2, rx, ry);
127   }
128 }
129 
130 
131 static void
goom_lines_move(GMLine * l)132 goom_lines_move (GMLine * l)
133 {
134   int i;
135   unsigned char *c1, *c2;
136 
137   for (i = 0; i < 512; i++) {
138     l->points[i].x = (l->points2[i].x + 39.0f * l->points[i].x) / 40.0f;
139     l->points[i].y = (l->points2[i].y + 39.0f * l->points[i].y) / 40.0f;
140     l->points[i].angle =
141         (l->points2[i].angle + 39.0f * l->points[i].angle) / 40.0f;
142   }
143 
144   c1 = (unsigned char *) &l->color;
145   c2 = (unsigned char *) &l->color2;
146   for (i = 0; i < 4; i++) {
147     int cc1, cc2;
148 
149     cc1 = *c1;
150     cc2 = *c2;
151     *c1 = (unsigned char) ((cc1 * 63 + cc2) >> 6);
152     ++c1;
153     ++c2;
154   }
155 
156   l->power += l->powinc;
157   if (l->power < 1.1f) {
158     l->power = 1.1f;
159     l->powinc = (float) (goom_irand (l->goomInfo->gRandom, 20) + 10) / 300.0f;
160   }
161   if (l->power > 17.5f) {
162     l->power = 17.5f;
163     l->powinc = -(float) (goom_irand (l->goomInfo->gRandom, 20) + 10) / 300.0f;
164   }
165 
166   l->amplitude = (99.0f * l->amplitude + l->amplitudeF) / 100.0f;
167 }
168 
169 void
goom_lines_switch_to(GMLine * gml,int IDdest,float param,float amplitude,int col)170 goom_lines_switch_to (GMLine * gml, int IDdest,
171     float param, float amplitude, int col)
172 {
173   genline (IDdest, param, gml->points2, gml->screenX, gml->screenY);
174   gml->IDdest = IDdest;
175   gml->param = param;
176   gml->amplitudeF = amplitude;
177   gml->color2 = getcouleur (col);
178 }
179 
180 GMLine *
goom_lines_init(PluginInfo * goomInfo,int rx,int ry,int IDsrc,float paramS,int coulS,int IDdest,float paramD,int coulD)181 goom_lines_init (PluginInfo * goomInfo, int rx, int ry,
182     int IDsrc, float paramS, int coulS, int IDdest, float paramD, int coulD)
183 {
184   GMLine *l = (GMLine *) malloc (sizeof (GMLine));
185 
186   l->goomInfo = goomInfo;
187 
188   l->points = (GMUnitPointer *) malloc (512 * sizeof (GMUnitPointer));
189   l->points2 = (GMUnitPointer *) malloc (512 * sizeof (GMUnitPointer));
190   l->nbPoints = 512;
191 
192   l->IDdest = IDdest;
193   l->param = paramD;
194 
195   l->amplitude = l->amplitudeF = 1.0f;
196 
197   genline (IDsrc, paramS, l->points, rx, ry);
198   genline (IDdest, paramD, l->points2, rx, ry);
199 
200   l->color = getcouleur (coulS);
201   l->color2 = getcouleur (coulD);
202 
203   l->screenX = rx;
204   l->screenY = ry;
205 
206   l->power = 0.0f;
207   l->powinc = 0.01f;
208 
209   goom_lines_switch_to (l, IDdest, paramD, 1.0f, coulD);
210 
211   return l;
212 }
213 
214 void
goom_lines_free(GMLine ** l)215 goom_lines_free (GMLine ** l)
216 {
217   free ((*l)->points2);
218   free ((*l)->points);
219   free (*l);
220   l = NULL;
221 }
222 
223 void
goom_lines_draw(PluginInfo * plug,GMLine * line,gint16 data[512],Pixel * p)224 goom_lines_draw (PluginInfo * plug, GMLine * line, gint16 data[512], Pixel * p)
225 {
226   if (line != NULL) {
227     int i, x1, y1;
228     guint32 color = line->color;
229     GMUnitPointer *pt = &(line->points[0]);
230 
231     float cosa = cos (pt->angle) / 1000.0f;
232     float sina = sin (pt->angle) / 1000.0f;
233 
234     lightencolor (&color, line->power);
235 
236     x1 = (int) (pt->x + cosa * line->amplitude * data[0]);
237     y1 = (int) (pt->y + sina * line->amplitude * data[0]);
238 
239     for (i = 1; i < 512; i++) {
240       int x2, y2;
241       GMUnitPointer *pt = &(line->points[i]);
242 
243       float cosa = cos (pt->angle) / 1000.0f;
244       float sina = sin (pt->angle) / 1000.0f;
245 
246       x2 = (int) (pt->x + cosa * line->amplitude * data[i]);
247       y2 = (int) (pt->y + sina * line->amplitude * data[i]);
248 
249       plug->methods.draw_line (p, x1, y1, x2, y2, color, line->screenX,
250           line->screenY);
251 
252       x1 = x2;
253       y1 = y2;
254     }
255     goom_lines_move (line);
256   }
257 }
258