3 /* Plasma "plugin" for Sherman's aquarium by Jonas Aaberg <cja@gmx.net> 2002 */
7 This plasma is based upon Jeremy Longley's JCL plasma for MS-DOS
8 that was written probably around 1995.
19 #define MAX_FRAMES 1000
20 #define GEN_PALETTE 11
21 #define GEN_MOVEMENT 10
22 #define START_UP_PLASMA 13
24 static unsigned char *surface = NULL, *movement = NULL, *palette = NULL, *pscreen = NULL;
28 static int p1, p2, p3, p4, p5, p6;
29 static int m1, m2, m3, m4;
30 static int c1, c2, c3, c11, c21, c31;
32 static int surface_x = 512;
33 static int surface_y = 300;
37 void plasma_exit(void)
42 void plasma_init(void)
44 surface = movement = palette = pscreen = NULL;
57 surface = movement = palette = pscreen = NULL;
62 void plasma_gen_surface(int start_num)
68 for(y = start_num * (surface_y / 10); y < ((start_num + 1) * surface_y / 10); y++){
69 ypos = (int) y * surface_x;
70 for(x = 0; x < surface_x; x++){
71 value = 64 + (unsigned char)(10 * (sin(x / p1) + cos(y / p2) +
72 cos(x / p3) + sin(y / p4) +
74 cos(hypot(256 - x, 150 - y) / p6)));
75 surface[ypos+(int)x] = value;
83 void plasma_start(void)
87 ad = aquarium_get_settings_ptr();
91 /* Surface randomization */
92 p1 = g_rand_int_range(ad->rnd, 1, 101);
93 p2 = p1 + g_rand_int_range(ad->rnd, -25, 25);
94 p3 = g_rand_int_range(ad->rnd, 1, 101);
95 p4 = p3 + g_rand_int_range(ad->rnd, -25, 25);
96 p5 = g_rand_int_range(ad->rnd, 1, 101);
97 p6 = p5 + g_rand_int_range(ad->rnd, -25, 25);
99 /* Movement randomization */
100 m1 = g_rand_int_range(ad->rnd, 1, 101);
101 m2 = g_rand_int_range(ad->rnd, 1, 101);
102 m3 = g_rand_int_range(ad->rnd, 1, 101);
103 m4 = g_rand_int_range(ad->rnd, 1, 101);
105 /* Colour randomization */
107 c1 = g_rand_int_range(ad->rnd, 1, 101);
108 c11 = g_rand_int_range(ad->rnd, 1, 101);
109 c2 = g_rand_int_range(ad->rnd, 1, 101);
110 c21 = g_rand_int_range(ad->rnd, 1, 101);
111 c3 = g_rand_int_range(ad->rnd, 1, 101);
112 c31= g_rand_int_range(ad->rnd, 1, 101);
118 ad = aquarium_get_settings_ptr();
120 /* Allocating memory */
122 surface_x = ((int)(ad->xmax / 512.0 + 1)) * 512;
123 surface_y = 2 * ad->ymax;
125 surface = g_malloc0(surface_x * surface_y);
126 movement = g_malloc0(4 * MAX_FRAMES);
127 palette = g_malloc0(3 * 2 * MAX_FRAMES);
130 pscreen = g_malloc0(ad->xmax*ad->ymax * 4);
134 void plasma_start_2(int start_num)
139 if(start_num < GEN_MOVEMENT)
140 plasma_gen_surface(start_num);
141 if(start_num == GEN_MOVEMENT){
143 for(count = 0; count < MAX_FRAMES; count++){
144 lead = (int)((surface_y / 3 - 4) + (surface_y / 3 - 10) * cos(count / m1)
145 + surface_x * (int)((surface_y / 6 - 2) + (surface_y / 6 - 3) * sin(count / m2)));
146 offset = (int)((surface_y / 3 - 4) + (surface_y / 3 - 8) * sin(count / m3)
147 + surface_x * (int)((surface_y / 6 - 2) + (surface_y / 6 - 3) * cos(count / m4))
149 movement[(int)count * 4 + 0] = (unsigned char)((lead & 0xff00) >> 8);
150 movement[(int)count * 4 + 1] = (unsigned char)(lead & 0xff);
151 movement[(int)count * 4 + 2] = (unsigned char)((offset & 0xff00) >> 8);
152 movement[(int)count * 4 + 3] = (unsigned char)(offset & 0xff);
156 if(start_num == GEN_PALETTE){
157 for(count = 0; count < (((MAX_FRAMES + 768) / 256 + 1) * 256); count++){
158 palette[(int)count * 3 + 0] = (unsigned char)(sin(count / c11) * sin(count / c1) * 126 + 126);
159 palette[(int)count * 3 + 1] = (unsigned char)(sin(count / c21) * sin(count / c2) * 126 + 126);
160 palette[(int)count * 3 + 2] = (unsigned char)(sin(count / c31) * sin(count / c3) * 126 + 126);
167 void plasma_update(void)
169 unsigned int lead, offset;
178 if(frame == MAX_FRAMES){
184 if(frame < START_UP_PLASMA){
185 plasma_start_2(frame - 1);
189 t = movement[frame * 4 + 1];
190 lead = (unsigned int)t;
191 t = movement[frame * 4 + 0];
192 lead += ((unsigned int)t) << 8;
194 t = movement[frame * 4 + 3];
195 offset = (unsigned int)t;
196 t = movement[frame * 4 + 2];
197 offset += ((unsigned int)t) << 8;
199 sum = (offset + lead) & 0xffff;
201 ad = aquarium_get_settings_ptr();
203 for(y = 0; y < ad->ymax; y++){
204 ypos = y * ad->xmax * 4;
205 for(x = 0; x < ad->xmax; x++){
206 t = (unsigned char)((surface[lead + surface_ptr + x] + surface[sum + surface_ptr + x]) & 0xff);
208 pscreen[ypos + x * 4 + 0] = palette[3 * frame + p + 0];
209 pscreen[ypos + x * 4 + 1] = palette[3 * frame + p + 1];
210 pscreen[ypos + x * 4 + 2] = palette[3 * frame + p + 2];
211 // pscreen[ypos + x * 4 + 3] = 'E';
213 surface_ptr += surface_x;
216 over_draw(0, 0, 0, ad->xmax, ad->ymax,pscreen);