Subversion Repositories shark

Rev

Rev 1567 | 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
 
1606 tullio 13
/*
14
 * This program is free software; you can redistribute it and/or modify
15
 * it under the terms of the GNU General Public License as published by
16
 * the Free Software Foundation; either version 2 of the License, or
17
 * (at your option) any later version.
18
 *
19
 * This program is distributed in the hope that it will be useful,
20
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
 * GNU General Public License for more details.
23
 *
24
 * You should have received a copy of the GNU General Public License
25
 * along with this program; if not, write to the Free Software
26
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
27
 *
28
 */
29
 
1162 tavani 30
#include "asteroid.h"
31
 
32
PID pid_RC;
33
int nrock;
34
int kill_rock;
35
rock_pos rocks[ROCK_NMAX];
36
 
1567 mauro 37
void draw_rock(int x, int y, int r, int c, int m)
1162 tavani 38
{
39
        sem_wait(&mx_grf);
1567 mauro 40
        if (m==0)
41
                grx_disc(x, y, r, c);
42
        else
43
                grx_circle(x, y, r, c);
1162 tavani 44
        sem_post(&mx_grf);
45
}
46
 
47
TASK rock(rock_ini* ri)
48
{
49
        int   x, y, r;  /* rock graphic position */
50
        int   ox,  oy;  /* rock old position */
51
        int   x0,  y0;  /* rock initial position */
52
        float vx,  vy;  /* rock speed */
53
        float vxo, vyo; /* rock initial speed */
54
        float ty,  tx;  
55
        float dt;      
56
        float rand_ang;
57
        int   rand_side;
58
        int   ab, ax, ay, i, l;
59
 
60
        x = y = x0 = y0 = ox = oy = vx = vy = ab = 0;
61
 
62
        i = ri->i;
63
        r = ri->r;
64
 
65
        rand_ang = ((rand()%120) - 60) * PI / 180.;
66
 
67
        sem_wait(&mx_st_scr);
68
        l = score / 50;
69
        sem_post(&mx_st_scr);
70
 
71
        sem_wait(&mx_mat);
72
        vxo = - (ROCK_VEL + l) * sin(rand_ang);
73
        vyo = - (ROCK_VEL + l) * cos(rand_ang);
74
        sem_post(&mx_mat);
75
 
76
#ifdef ASTRO_MOVE
77
        rand_side = rand()%4;
78
#else
79
        rand_side = 1;
80
#endif
81
 
82
        if (rand_side == 0) { // Bottom
83
                vx =  vxo;
84
                vy =  vyo;
85
        }
86
        if (rand_side == 1) { // Top
87
                vx = -vxo;
88
                vy = -vyo;
89
        }
90
        if (rand_side == 2) { // Right
91
                vx =  vyo;
92
                vy = -vxo;
93
        }
94
        if (rand_side == 3) { // Left
95
                vx = -vyo;
96
                vy =  vxo;
97
        }
98
 
99
        if ( (ri->x == 0) && (ri->y == 0) ) {
100
                if (rand_side < 2) { // Bottom or Top
101
                        x = ox = x0 = GB_XMIN + (GB_XMAX-GB_XMIN)/4 + (rand()%((GB_XMAX-GB_XMIN)/2));
102
                        if (rand_side == 0) { // Bottom
103
                                y = oy = y0 = GB_YMAX - (r+1);
104
                        }
105
                        if (rand_side == 1) { // Top
106
                                y = oy = y0 = GB_YMIN + (r+1);
107
                        }
108
                } else {
109
                        y = oy = y0 = GB_YMIN + (GB_YMAX-GB_YMIN)/4 + (rand()%((GB_YMAX-GB_YMIN)/2));
110
                        if (rand_side == 2) { // Right
111
                                x = ox = x0 = GB_XMAX - (r+1);
112
                        }
113
                        if (rand_side == 3) { // Left
114
                                x = ox = x0 = GB_XMIN + (r+1);
115
                        }
116
                }
117
        } else {
118
                x = ox = x0 = ri->x;
119
                y = oy = y0 = ri->y;
120
        }
121
 
122
        sem_wait(&mx_rk);
123
        rocks[i].x = x;
124
        rocks[i].y = y;
125
        rocks[i].r = r;
126
        sem_post(&mx_rk);
127
 
128
        tx = 0;
129
        ty = 0;
130
        dt = ((float)ROCK_PERIOD)/100000;
131
 
132
        while (1) {
133
                y = y0 + vy * ty;
134
                x = x0 + vx * tx;
135
 
136
                sem_wait(&mx_rk);
137
                rocks[i].x = x;
138
                rocks[i].y = y;
139
                r = rocks[i].r;
140
                sem_post(&mx_rk);
141
 
1567 mauro 142
                draw_rock(ox, oy, r, RGB_BLACK, 0);
1162 tavani 143
 
144
                if ((kill_rock) || (crash)){
145
                        nrock--;
146
                        sem_wait(&mx_rk);
147
                        rocks[i].pid = NIL;
148
                        sem_post(&mx_rk);
149
                        return 0;
150
                }
151
 
152
                ox = x;
153
                oy = y;
154
 
155
                sem_wait(&mx_xy);
156
                ax = astro_x;
157
                ay = astro_y;
158
                sem_post(&mx_xy);
159
 
160
                if (dist_xy(x, y, ax, ay) < (ASTRO_RADIUS/2+r)) {
161
                        if (!ab) {
162
                                sem_wait(&mx_st_nrg);
163
                                energy -= ENERGY_GOT;
164
                                sem_post(&mx_st_nrg);
165
                                ab = 1;
166
                        }
167
                } else
168
                        ab = 0;
169
 
170
                sem_wait(&mx_xy);
171
                if (dist_xy(x, y, astro_x, astro_y) < (ASTRO_RADIUS+r)/2) crash = 1;
172
                sem_post(&mx_xy);
173
 
174
#ifdef ASTRO_MOVE
175
                if (x <= GB_XMIN + r) {
176
                        x0 = x = GB_XMAX - (r+1);
177
                        y0 = y;
178
                        tx = ty = 0;
179
                }
180
                if (x >= GB_XMAX - r) {
181
                        x0 = x = GB_XMIN + (r+1);
182
                        y0 = y;
183
                        tx = ty = 0;
184
                }
185
                if (y <= GB_YMIN + r) {
186
                        x0 = x;
187
                        y0 = y = GB_YMAX - (r+1);
188
                        tx = ty = 0;
189
                }
190
                if (y >= GB_YMAX - r) {
191
                        x0 = x;
192
                        y0 = y = GB_YMIN + (r+1);
193
                        tx = ty = 0;
194
                }
195
#else
196
                if ( (x <= GB_XMIN + r) || (x >= GB_XMAX - r) || (y >= GB_YMAX - 2*r) ) {
197
                        if (y >= GB_YMAX - 2*r) {
198
                                sem_wait(&mx_st_nrg);
199
                                energy -= ENERGY_GOT;
200
                                sem_post(&mx_st_nrg);
201
                        }
202
                        nrock--;
203
                        sem_wait(&mx_rk);
204
                        rocks[i].pid = NIL;
205
                        sem_post(&mx_rk);
206
                        return 0;
207
                }
208
#endif
1567 mauro 209
                draw_rock(ox, oy, r, RGB_YELLOW, 1);
1162 tavani 210
 
211
                ty += dt;
212
                tx += dt;
213
 
214
                task_endcycle();
215
        }
216
}
217
 
218
void rock_create(rock_ini* ri)
219
{
220
        SOFT_TASK_MODEL mp;
221
        PID pid;
222
        int i;
223
 
224
        soft_task_default_model(mp);
225
        soft_task_def_ctrl_jet(mp);
226
        soft_task_def_group(mp, ROCK_GROUP);
227
        soft_task_def_met(mp, ROCK_WCET);
228
        soft_task_def_period(mp,ROCK_PERIOD);
229
        soft_task_def_usemath(mp);
230
        i = -1;
231
        do {
232
                i++;
233
                sem_wait(&mx_rk);
234
                pid = rocks[i].pid;
235
                sem_post(&mx_rk);
236
        } while (pid != NIL);
237
        ri->i = i;
238
        soft_task_def_arg(mp, (void *)ri);
239
        pid = task_create("Rock", rock, &mp, NULL);
240
 
241
        if (pid != NIL) {
242
                sem_wait(&mx_rk);
243
                rocks[i].pid = pid;
244
                sem_post(&mx_rk);
245
                task_activate(pid);
246
                nrock++;
247
        }
248
}
249
 
250
TASK rock_creator()
251
{
252
        while (1) {
253
                sem_wait(&mx_rn);
254
                if (rock_new.i == 0) {
255
                        rock_create(&rock_new);
256
                        rock_new.i = -1;
257
                }
258
                sem_post(&mx_rn);
259
 
260
                if ((nrock < ROCK_NMAX/2) && (!kill_rock) && (!crash)) {
261
                        if ((rand()%ROCK_NMAX) > nrock) {
262
                                rock_new.r = ROCK_RADIUS_I;
263
                                rock_new.x = rock_new.y = 0;
264
                                rock_create(&rock_new);
265
                        }
266
                }
267
                task_endcycle();
268
        }
269
}
270
 
271
void reset_rock()
272
{
273
        kill_rock = 1;
274
}
275
 
276
void start_rock()
277
{
278
        kill_rock = 0;
279
}
280
 
281
void create_rock_task()
282
{
283
        SOFT_TASK_MODEL ms;
284
 
285
        soft_task_default_model(ms);
286
        soft_task_def_ctrl_jet(ms);
287
        soft_task_def_met(ms, ROCK_WCET);
288
        soft_task_def_period(ms,ROCK_PERIOD*10);
289
        soft_task_def_usemath(ms);
290
        pid_RC = task_create("RockCreator", rock_creator, &ms, NULL);
291
        if (pid_RC == NIL) {
1376 giacomo 292
                sys_shutdown_message("Could not create task <RockCreator>\n");
1550 pj 293
                exit(1);
1162 tavani 294
        } else
295
                task_activate(pid_RC);
296
}
297
 
298
void init_rock()
299
{
300
        int i;
301
 
302
        nrock = 0;
303
        kill_rock = 1;
304
        for ( i=0; i<ROCK_NMAX; i++ ) rocks[i].pid = NIL;
305
 
306
        create_rock_task();
307
}
308