comparison src/paranormal/misc.c @ 186:49f532942eec trunk

[svn] - add floating particles.
author nenolod
date Thu, 02 Nov 2006 02:30:44 -0800
parents
children 0d826917c56f
comparison
equal deleted inserted replaced
185:38526384bc79 186:49f532942eec
1 #ifdef HAVE_CONFIG_H
2 # include <config.h>
3 #endif
4
5 #include <stdlib.h>
6 #include <stdio.h>
7
8 #include <glib.h>
9
10 #include "paranormal.h"
11 #include "actuators.h"
12 #include "pn_utils.h"
13
14 /* ******************** misc_floater ******************** */
15 static struct pn_actuator_option_desc misc_floater_opts[] =
16 {
17 { "value", "The colour value for the floater.",
18 OPT_TYPE_INT, { ival: 255 } },
19 { 0 }
20 };
21
22 typedef enum
23 {
24 float_up = 0x1,
25 float_down = 0x2,
26 float_left = 0x4,
27 float_right = 0x8,
28 } FloaterDirection;
29
30 struct floater_state_data
31 {
32 FloaterDirection dir;
33 gint x;
34 gint y;
35 };
36
37 static void
38 misc_floater_init(gpointer *data)
39 {
40 struct floater_state_data *opaque_data = g_new0(struct floater_state_data, 1);
41 *data = opaque_data;
42 opaque_data->x = rand() % pn_image_data->width;
43 opaque_data->y = rand() % pn_image_data->height;
44 opaque_data->dir = (FloaterDirection) rand() % 15; /* sum of all dir values */
45 }
46
47 static void
48 misc_floater_cleanup(gpointer data)
49 {
50 g_free(data);
51 }
52
53 /*
54 * This implementation isn't very great.
55 * Anyone want to improve it? :(
56 */
57 static void
58 misc_floater_exec(const struct pn_actuator_option *opts, gpointer data)
59 {
60 struct floater_state_data *opaque_data = (struct floater_state_data *) data;
61 guchar value = (opts[0].val.ival < 0 || opts[0].val.ival > 255) ? 255 : opts[0].val.ival;
62
63 /* determine the root coordinate first */
64 if (opaque_data->dir & float_up)
65 opaque_data->y -= 1;
66 if (opaque_data->dir & float_down)
67 opaque_data->y += 1;
68
69 if (opaque_data->dir & float_left)
70 opaque_data->x -= 1;
71 if (opaque_data->dir & float_right)
72 opaque_data->x += 1;
73
74 /* make sure we're within surface boundaries. segfaults suck, afterall. */
75 if (opaque_data->x + 1 <= pn_image_data->width &&
76 opaque_data->x - 1 >= 0 &&
77 opaque_data->y + 1 <= pn_image_data->height &&
78 opaque_data->y - 1 >= 0)
79 {
80 /* draw it. i could use a loop here, but i don't see much reason in it,
81 * so i don't think i will at this time. -nenolod
82 */
83 pn_image_data->surface[0][PN_IMG_INDEX(opaque_data->x, opaque_data->y)] = value;
84 pn_image_data->surface[0][PN_IMG_INDEX(opaque_data->x + 1, opaque_data->y)] = value;
85 pn_image_data->surface[0][PN_IMG_INDEX(opaque_data->x - 1, opaque_data->y)] = value;
86 pn_image_data->surface[0][PN_IMG_INDEX(opaque_data->x, opaque_data->y + 1)] = value;
87 pn_image_data->surface[0][PN_IMG_INDEX(opaque_data->x, opaque_data->y - 1)] = value;
88 }
89
90 /* check if we need to change direction yet, and if so, do so. */
91 if (pn_is_new_beat() == TRUE)
92 opaque_data->dir = (FloaterDirection) rand() % 15; /* sum of all dir values */
93
94 /* now adjust the direction so we stay in boundary */
95 if (opaque_data->x - 1 <= 0 && opaque_data->dir & float_left)
96 {
97 opaque_data->dir &= ~float_left;
98 opaque_data->dir |= float_right;
99 }
100
101 if (opaque_data->x + 1 >= pn_image_data->width && opaque_data->dir & float_right)
102 {
103 opaque_data->dir &= ~float_right;
104 opaque_data->dir |= float_left;
105 }
106
107 if (opaque_data->y - 1 <= 0 && opaque_data->dir & float_up)
108 {
109 opaque_data->dir &= ~float_up;
110 opaque_data->dir |= float_down;
111 }
112
113 if (opaque_data->y + 1 >= pn_image_data->height && opaque_data->dir & float_down)
114 {
115 opaque_data->dir &= ~float_down;
116 opaque_data->dir |= float_up;
117 }
118 }
119
120 struct pn_actuator_desc builtin_misc_floater =
121 {
122 "misc_floater",
123 "Floating Particle",
124 "A floating particle.",
125 0, misc_floater_opts,
126 misc_floater_init, misc_floater_cleanup, misc_floater_exec
127 };
128