Subversion Repositories shark

Rev

Rev 1376 | Rev 1392 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1162 tavani 1
/*
1349 giacomo 2
 * Project: S.Ha.R.K.
1162 tavani 3
 *
4
 * Coordinators: Giorgio Buttazzo <giorgio@sssup.it>
5
 *
6
 * ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
7
 *
8
 * http://www.sssup.it
9
 * http://retis.sssup.it
10
 * http://hartik.sssup.it
11
 */
12
 
13
#include "asteroid.h"
14
 
15
PID pid_RC;
16
int nrock;
17
int kill_rock;
18
rock_pos rocks[ROCK_NMAX];
19
 
1378 giacomo 20
extern PID shutdown_task_PID;
1373 giacomo 21
 
1162 tavani 22
void draw_rock(int x, int y, int r, int c)
23
{
24
        sem_wait(&mx_grf);
25
        grx_disc(x, y, r, c);
26
        sem_post(&mx_grf);
27
}
28
 
29
TASK rock(rock_ini* ri)
30
{
31
        int   x, y, r;  /* rock graphic position */
32
        int   ox,  oy;  /* rock old position */
33
        int   x0,  y0;  /* rock initial position */
34
        float vx,  vy;  /* rock speed */
35
        float vxo, vyo; /* rock initial speed */
36
        float ty,  tx;  
37
        float dt;      
38
        float rand_ang;
39
        int   rand_side;
40
        int   ab, ax, ay, i, l;
41
 
42
        x = y = x0 = y0 = ox = oy = vx = vy = ab = 0;
43
 
44
        i = ri->i;
45
        r = ri->r;
46
 
47
        rand_ang = ((rand()%120) - 60) * PI / 180.;
48
 
49
        sem_wait(&mx_st_scr);
50
        l = score / 50;
51
        sem_post(&mx_st_scr);
52
 
53
        sem_wait(&mx_mat);
54
        vxo = - (ROCK_VEL + l) * sin(rand_ang);
55
        vyo = - (ROCK_VEL + l) * cos(rand_ang);
56
        sem_post(&mx_mat);
57
 
58
#ifdef ASTRO_MOVE
59
        rand_side = rand()%4;
60
#else
61
        rand_side = 1;
62
#endif
63
 
64
        if (rand_side == 0) { // Bottom
65
                vx =  vxo;
66
                vy =  vyo;
67
        }
68
        if (rand_side == 1) { // Top
69
                vx = -vxo;
70
                vy = -vyo;
71
        }
72
        if (rand_side == 2) { // Right
73
                vx =  vyo;
74
                vy = -vxo;
75
        }
76
        if (rand_side == 3) { // Left
77
                vx = -vyo;
78
                vy =  vxo;
79
        }
80
 
81
        if ( (ri->x == 0) && (ri->y == 0) ) {
82
                if (rand_side < 2) { // Bottom or Top
83
                        x = ox = x0 = GB_XMIN + (GB_XMAX-GB_XMIN)/4 + (rand()%((GB_XMAX-GB_XMIN)/2));
84
                        if (rand_side == 0) { // Bottom
85
                                y = oy = y0 = GB_YMAX - (r+1);
86
                        }
87
                        if (rand_side == 1) { // Top
88
                                y = oy = y0 = GB_YMIN + (r+1);
89
                        }
90
                } else {
91
                        y = oy = y0 = GB_YMIN + (GB_YMAX-GB_YMIN)/4 + (rand()%((GB_YMAX-GB_YMIN)/2));
92
                        if (rand_side == 2) { // Right
93
                                x = ox = x0 = GB_XMAX - (r+1);
94
                        }
95
                        if (rand_side == 3) { // Left
96
                                x = ox = x0 = GB_XMIN + (r+1);
97
                        }
98
                }
99
        } else {
100
                x = ox = x0 = ri->x;
101
                y = oy = y0 = ri->y;
102
        }
103
 
104
        sem_wait(&mx_rk);
105
        rocks[i].x = x;
106
        rocks[i].y = y;
107
        rocks[i].r = r;
108
        sem_post(&mx_rk);
109
 
110
        tx = 0;
111
        ty = 0;
112
        dt = ((float)ROCK_PERIOD)/100000;
113
 
114
        while (1) {
115
                y = y0 + vy * ty;
116
                x = x0 + vx * tx;
117
 
118
                sem_wait(&mx_rk);
119
                rocks[i].x = x;
120
                rocks[i].y = y;
121
                r = rocks[i].r;
122
                sem_post(&mx_rk);
123
 
124
                draw_rock(ox, oy, r, RGB_BLACK);
125
 
126
                if ((kill_rock) || (crash)){
127
                        nrock--;
128
                        sem_wait(&mx_rk);
129
                        rocks[i].pid = NIL;
130
                        sem_post(&mx_rk);
131
                        return 0;
132
                }
133
 
134
                ox = x;
135
                oy = y;
136
 
137
                sem_wait(&mx_xy);
138
                ax = astro_x;
139
                ay = astro_y;
140
                sem_post(&mx_xy);
141
 
142
                if (dist_xy(x, y, ax, ay) < (ASTRO_RADIUS/2+r)) {
143
                        if (!ab) {
144
                                sem_wait(&mx_st_nrg);
145
                                energy -= ENERGY_GOT;
146
                                sem_post(&mx_st_nrg);
147
                                ab = 1;
148
                        }
149
                } else
150
                        ab = 0;
151
 
152
                sem_wait(&mx_xy);
153
                if (dist_xy(x, y, astro_x, astro_y) < (ASTRO_RADIUS+r)/2) crash = 1;
154
                sem_post(&mx_xy);
155
 
156
#ifdef ASTRO_MOVE
157
                if (x <= GB_XMIN + r) {
158
                        x0 = x = GB_XMAX - (r+1);
159
                        y0 = y;
160
                        tx = ty = 0;
161
                }
162
                if (x >= GB_XMAX - r) {
163
                        x0 = x = GB_XMIN + (r+1);
164
                        y0 = y;
165
                        tx = ty = 0;
166
                }
167
                if (y <= GB_YMIN + r) {
168
                        x0 = x;
169
                        y0 = y = GB_YMAX - (r+1);
170
                        tx = ty = 0;
171
                }
172
                if (y >= GB_YMAX - r) {
173
                        x0 = x;
174
                        y0 = y = GB_YMIN + (r+1);
175
                        tx = ty = 0;
176
                }
177
#else
178
                if ( (x <= GB_XMIN + r) || (x >= GB_XMAX - r) || (y >= GB_YMAX - 2*r) ) {
179
                        if (y >= GB_YMAX - 2*r) {
180
                                sem_wait(&mx_st_nrg);
181
                                energy -= ENERGY_GOT;
182
                                sem_post(&mx_st_nrg);
183
                        }
184
                        nrock--;
185
                        sem_wait(&mx_rk);
186
                        rocks[i].pid = NIL;
187
                        sem_post(&mx_rk);
188
                        return 0;
189
                }
190
#endif
191
                draw_rock(ox, oy, r, RGB_YELLOW);
192
 
193
                ty += dt;
194
                tx += dt;
195
 
196
                task_endcycle();
197
        }
198
}
199
 
200
void rock_create(rock_ini* ri)
201
{
202
        SOFT_TASK_MODEL mp;
203
        PID pid;
204
        int i;
205
 
206
        soft_task_default_model(mp);
207
        soft_task_def_ctrl_jet(mp);
208
        soft_task_def_group(mp, ROCK_GROUP);
209
        soft_task_def_met(mp, ROCK_WCET);
210
        soft_task_def_period(mp,ROCK_PERIOD);
211
        soft_task_def_usemath(mp);
212
        i = -1;
213
        do {
214
                i++;
215
                sem_wait(&mx_rk);
216
                pid = rocks[i].pid;
217
                sem_post(&mx_rk);
218
        } while (pid != NIL);
219
        ri->i = i;
220
        soft_task_def_arg(mp, (void *)ri);
221
        pid = task_create("Rock", rock, &mp, NULL);
222
 
223
        if (pid != NIL) {
224
                sem_wait(&mx_rk);
225
                rocks[i].pid = pid;
226
                sem_post(&mx_rk);
227
                task_activate(pid);
228
                nrock++;
229
        }
230
}
231
 
232
TASK rock_creator()
233
{
234
        while (1) {
235
                sem_wait(&mx_rn);
236
                if (rock_new.i == 0) {
237
                        rock_create(&rock_new);
238
                        rock_new.i = -1;
239
                }
240
                sem_post(&mx_rn);
241
 
242
                if ((nrock < ROCK_NMAX/2) && (!kill_rock) && (!crash)) {
243
                        if ((rand()%ROCK_NMAX) > nrock) {
244
                                rock_new.r = ROCK_RADIUS_I;
245
                                rock_new.x = rock_new.y = 0;
246
                                rock_create(&rock_new);
247
                        }
248
                }
249
                task_endcycle();
250
        }
251
}
252
 
253
void reset_rock()
254
{
255
        kill_rock = 1;
256
}
257
 
258
void start_rock()
259
{
260
        kill_rock = 0;
261
}
262
 
263
void create_rock_task()
264
{
265
        SOFT_TASK_MODEL ms;
266
 
267
        soft_task_default_model(ms);
268
        soft_task_def_ctrl_jet(ms);
269
        soft_task_def_met(ms, ROCK_WCET);
270
        soft_task_def_period(ms,ROCK_PERIOD*10);
271
        soft_task_def_usemath(ms);
272
        pid_RC = task_create("RockCreator", rock_creator, &ms, NULL);
273
        if (pid_RC == NIL) {
1376 giacomo 274
                sys_shutdown_message("Could not create task <RockCreator>\n");
1378 giacomo 275
                task_activate(shutdown_task_PID);
1376 giacomo 276
                return;
1162 tavani 277
        } else
278
                task_activate(pid_RC);
279
}
280
 
281
void init_rock()
282
{
283
        int i;
284
 
285
        nrock = 0;
286
        kill_rock = 1;
287
        for ( i=0; i<ROCK_NMAX; i++ ) rocks[i].pid = NIL;
288
 
289
        create_rock_task();
290
}
291