Subversion Repositories shark

Rev

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

Rev Author Line No. Line
1162 tavani 1
/*
2
 * Project: S.Ha.R.K.
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://shark.sssup.it
11
 */
12
 
13
#include "asteroid.h"
14
 
15
int nshot;             /* number of shot active */
16
int astro_x, astro_y;  /* astro position */
17
int astro_grad;        /* astro angolar position */
18
PID pid_TR, pid_TL;    /* pid of turn tasks */
19
int astro_vel;         /* astro speed */
20
PID pid_SU, pid_SD;    /* pid of acc tasks */
21
PID pid_SZ, pid_FL;    /* pid of acc tasks */
22
int freez_astro;       /* turn of pad*/
23
int kill_shot;
24
 
25
rock_ini rock_new;
26
 
27
TASK shot(int i)
28
{
29
        int   x, y;   /* shot graphic position  */
30
        int   ox, oy; /* shot old position      */
31
        int   x0, y0; /* shot initial position  */
32
        float vx, vy; /* shot speed     */
33
        float ty, tx;
34
        float dt;
35
        float a_rad;
36
        int   a_vel;
37
 
38
        int      rx,  ry,  rr;
39
        PID      rp;
40
 
41
        sem_wait(&mx_xy);
42
        y = oy = y0 = astro_y;
43
        x = ox = x0 = astro_x;
44
        sem_post(&mx_xy);
45
 
46
        sem_wait(&mx_pos);
47
        a_rad = astro_grad * PI / 180.;
48
        sem_post(&mx_pos);
49
        sem_wait(&mx_vel);
50
        a_vel = astro_vel;
51
        sem_post(&mx_vel);
52
        sem_wait(&mx_mat);
53
        vx = - (SHOT_VEL + a_vel) * sin(a_rad);
54
        vy = - (SHOT_VEL + a_vel) * cos(a_rad);
55
        sem_post(&mx_mat);
56
        tx = 0;
57
        ty = 0;
58
        dt = ((float)SHOT_PERIOD)/100000;
59
 
60
        while (1) {
61
                y = y0 + vy * ty;
62
                x = x0 + vx * tx;
63
 
64
                sem_wait(&mx_grf);
65
                grx_disc(ox, oy, SHOT_RADIUS, RGB_BLACK);
66
                sem_post(&mx_grf);
67
                ox = x;
68
                oy = y;
69
 
70
                if ((kill_shot)||(crash)||(y < GB_YMIN+SHOT_RADIUS)||(x < GB_XMIN+SHOT_RADIUS)||(x > GB_XMAX-SHOT_RADIUS)||(y > GB_YMAX-SHOT_RADIUS)){
71
                        nshot--;
72
                        return 0;
73
                }
74
 
75
                for ( i=0; i<ROCK_NMAX; i++ ) {
76
                        sem_wait(&mx_rk);
77
                        rp = rocks[i].pid;
78
                        rx = rocks[i].x;
79
                        ry = rocks[i].y;
80
                        rr = rocks[i].r;
81
                        sem_post(&mx_rk);
82
 
83
                        if ((rp!=NIL) && (dist_xy(x, y, rx, ry) < (SHOT_RADIUS+rr))) {
1567 mauro 84
                                draw_rock(rx, ry, rr, RGB_BLACK, 0);
1162 tavani 85
                                if (rr == ROCK_RADIUS_I) {
86
                                        sem_wait(&mx_rk);
87
                                        rocks[i].r = ROCK_RADIUS_S;
88
                                        sem_post(&mx_rk);
89
                                        sem_wait(&mx_rn);
90
                                        rock_new.r = ROCK_RADIUS_S;
91
                                        rock_new.x = rx;
92
                                        rock_new.y = ry;
93
                                        rock_new.i = 0;
94
                                        sem_post(&mx_rn);
95
                                        sem_wait(&mx_st_scr);
96
                                        score += SCORE_GOT;
97
                                        sem_post(&mx_st_scr);
98
                                } else {
99
                                        task_kill(rp);
100
                                        sem_wait(&mx_rk);
101
                                        rocks[i].pid = NIL;
102
                                        sem_post(&mx_rk);
103
                                        nrock--;
104
                                        sem_wait(&mx_st_scr);
105
                                        score += 2*SCORE_GOT;
106
                                        sem_post(&mx_st_scr);
107
                                }
108
                                sem_wait(&mx_st_nrg);
109
                                energy += ENERGY_GOT;
110
                                sem_post(&mx_st_nrg);
111
                                sem_wait(&mx_st_kil);
112
                                enemy++;
113
                                sem_post(&mx_st_kil);
114
                                nshot--;
115
                                return 0;
116
                        }
117
                }
118
 
119
                sem_wait(&mx_grf);
120
                grx_disc(ox, oy, SHOT_RADIUS, RGB_RED);
121
                sem_post(&mx_grf);
122
 
123
                ty += dt;
124
                tx += dt;
125
 
126
                task_endcycle();
127
        }
128
}
129
 
130
TASK astro()
131
{
132
        float astro_rad;
133
        int ox, oy;
134
        float s, c;
135
 
136
        //leggo posizione
137
        sem_wait(&mx_pos);
138
        astro_rad = astro_grad * PI / 180.;
139
        sem_post(&mx_pos);
140
        sem_wait(&mx_mat);
141
        s = -sin(astro_rad);
142
        c = -cos(astro_rad);
143
        sem_post(&mx_mat);
144
        sem_wait(&mx_xy);
145
        ox = astro_x;
146
        oy = astro_y;
147
        sem_post(&mx_xy);
148
 
149
        while (1) {
150
 
151
                sem_wait(&mx_grf);
152
                //DRAW SHADOW ASTRO
153
                grx_line(ox + 15.*s       , oy + 15.*c       , ox -  5.*c -  9.*s, oy +  5.*s -  9.*c, RGB_BLACK);
154
                grx_line(ox + 15.*s       , oy + 15.*c       , ox +  5.*c -  9.*s, oy -  5.*s -  9.*c, RGB_BLACK);
155
                grx_line(ox               , oy               , ox - 12.*c -  9.*s, oy + 12.*s -  9.*c, RGB_BLACK);
156
                grx_line(ox               , oy               , ox + 12.*c -  9.*s, oy - 12.*s -  9.*c, RGB_BLACK);
157
                grx_line(ox - 12.*c - 9.*s, oy + 12.*s - 9.*c, ox + 12.*c -  9.*s, oy - 12.*s -  9.*c, RGB_BLACK);
158
                sem_post(&mx_grf);
159
 
160
                sem_wait(&mx_pos);
161
                astro_rad = astro_grad * PI / 180.;
162
                sem_post(&mx_pos);
163
                sem_wait(&mx_mat);
164
                s = -sin(astro_rad);
165
                c = -cos(astro_rad);
166
                sem_post(&mx_mat);
167
                sem_wait(&mx_xy);
168
                ox = astro_x;
169
                oy = astro_y;
170
                sem_post(&mx_xy);
171
 
172
                sem_wait(&mx_grf);
173
                //DRAW ASTRO
174
                grx_line(ox + 15.*s       , oy + 15.*c       , ox -  5.*c -  9.*s, oy +  5.*s -  9.*c, RGB_WHITE);
175
                grx_line(ox + 15.*s       , oy + 15.*c       , ox +  5.*c -  9.*s, oy -  5.*s -  9.*c, RGB_WHITE);
176
                grx_line(ox               , oy               , ox - 12.*c -  9.*s, oy + 12.*s -  9.*c, RGB_WHITE);
177
                grx_line(ox               , oy               , ox + 12.*c -  9.*s, oy - 12.*s -  9.*c, RGB_WHITE);
178
                grx_line(ox - 12.*c - 9.*s, oy + 12.*s - 9.*c, ox + 12.*c -  9.*s, oy - 12.*s -  9.*c, RGB_WHITE);
179
                sem_post(&mx_grf);
180
 
181
/*              {
182
                        int xxx;
183
                        for (xxx=0; xxx<10000; xxx++);
184
                }*/
185
 
186
                task_endcycle();
187
        }
188
}
189
 
190
TASK look()
191
{
192
        while (1) {
193
                if (crash) {
194
                        reset_rock();
195
                        reset_astro();
196
                        if (nrock==0) {
197
                                reset_game();
198
                                crash = 0;
199
                        }
200
                }
201
                task_endcycle();
202
        }
203
}
204
 
205
TASK turn(int i)
206
{
207
 
208
        while (1) {
209
 
210
                sem_wait(&mx_pos);
211
                if (i==0)
212
                        astro_grad += 180;
213
                else {
214
                        astro_grad += i;
215
                }
216
                if (astro_grad < -180) astro_grad += 360;
217
                if (astro_grad >  180) astro_grad -= 360;
218
                if (astro_grad < -ASTRO_MAX_GRAD) astro_grad = -ASTRO_MAX_GRAD;
219
                if (astro_grad >  ASTRO_MAX_GRAD) astro_grad =  ASTRO_MAX_GRAD;
220
                sem_post(&mx_pos);
221
 
222
                task_endcycle();
223
        }
224
}
225
 
226
TASK speed(int i)
227
{
228
 
229
        while (1) {
230
 
231
                sem_wait(&mx_vel);
232
                if (i==0)
233
                        astro_vel = 0;
234
                else {
235
                        astro_vel += i;
236
                        if (astro_vel < -ASTRO_MAX_VEL) astro_vel = -ASTRO_MAX_VEL;
237
                        if (astro_vel >  ASTRO_MAX_VEL) astro_vel =  ASTRO_MAX_VEL;
238
                }
239
                sem_post(&mx_vel);
240
 
241
                task_endcycle();
242
        }
243
}
244
 
245
TASK move()
246
{
247
        int dv, x, y;
248
        float drad;
249
 
250
        drad = x = y = 0;
251
 
252
        while (1) {
253
 
254
#ifdef ASTRO_MOVE
255
                sem_wait(&mx_pos);
256
                drad = astro_grad * PI / 180.;
257
                sem_post(&mx_pos);
258
#endif
259
                sem_wait(&mx_vel);
260
                dv = astro_vel;
261
                sem_post(&mx_vel);
262
                sem_wait(&mx_xy);
263
                x = astro_x;
264
                y = astro_y;
265
                sem_post(&mx_xy);
266
#ifdef ASTRO_MOVE
267
                x -= dv * sin(drad);
268
                y -= dv * cos(drad);
269
                if (x < GB_XMIN + ASTRO_RADIUS) x = GB_XMAX - ASTRO_RADIUS;
270
                if (x > GB_XMAX - ASTRO_RADIUS) x = GB_XMIN + ASTRO_RADIUS;
271
                if (y < GB_YMIN + ASTRO_RADIUS) y = GB_YMAX - ASTRO_RADIUS;
272
                if (y > GB_YMAX - ASTRO_RADIUS) y = GB_YMIN + ASTRO_RADIUS;
273
#else
274
                x += dv;
275
                if (x < GB_XMIN + 2*ASTRO_RADIUS) {
276
                        x = GB_XMIN + 2*ASTRO_RADIUS;
277
                        sem_wait(&mx_vel);
278
                        astro_vel = - astro_vel - ASTRO_VEL_INC;
279
                        sem_post(&mx_vel);
280
                }
281
                if (x > GB_XMAX - 2*ASTRO_RADIUS) {
282
                        x = GB_XMAX - 2*ASTRO_RADIUS;
283
                        sem_wait(&mx_vel);
284
                        astro_vel = - astro_vel + ASTRO_VEL_INC;
285
                        sem_post(&mx_vel);
286
                }
287
#endif
288
                sem_wait(&mx_xy);
289
                astro_x = x;
290
                astro_y = y;
291
                sem_post(&mx_xy);
292
 
293
                task_endcycle();
294
        }
295
}
296
 
297
void pad(KEY_EVT *k)
298
{
299
        if (freez_astro) return;
300
        if (k->scan == KEY_O) task_activate(pid_TL);
301
        if (k->scan == KEY_P) task_activate(pid_TR);
302
        if (k->scan == KEY_S) task_activate(pid_SZ);
303
        if (k->scan == KEY_Z) task_activate(pid_SD);
304
#ifdef ASTRO_MOVE
305
        if (k->scan == KEY_A) task_activate(pid_SU);
306
        if (k->scan == KEY_F) task_activate(pid_FL);
307
#else
308
        if (k->scan == KEY_X) task_activate(pid_SU);
309
#endif
310
}
311
 
312
void new_shot(KEY_EVT *k)
313
{
314
        SOFT_TASK_MODEL mp;
315
        PID pid;
316
 
317
        if ((nshot >= SHOT_NMAX)||(freez_astro)||(kill_shot)||(crash)) return;
318
 
319
        soft_task_default_model(mp);
320
        soft_task_def_ctrl_jet(mp);
321
        soft_task_def_arg(mp, (void *)nshot);
322
        soft_task_def_group(mp, SHOT_GROUP);
323
        soft_task_def_met(mp, SHOT_WCET);
324
        soft_task_def_period(mp,SHOT_PERIOD);
325
        soft_task_def_usemath(mp);
326
        pid = task_create("Shot", shot, &mp, NULL);
327
 
328
        if (pid != NIL) {
329
                task_activate(pid);
330
                nshot++;
331
                sem_wait(&mx_st_nrg);
332
                energy -= ENERGY_SHOT;
333
                sem_post(&mx_st_nrg);
334
        }
335
}
336
 
337
void start_astro()
338
{
339
        freez_astro = 0;
340
        kill_shot = 0;
341
}
342
 
343
void reset_astro()
344
{
345
        freez_astro = 1;
346
        sem_wait(&mx_xy);
347
        astro_x = ASTRO_X;
348
        astro_y = ASTRO_Y;
349
        sem_post(&mx_xy);
350
        sem_wait(&mx_pos);
351
        astro_grad = 0;
352
        sem_post(&mx_pos);
353
        sem_wait(&mx_vel);
354
        astro_vel = 0;
355
        sem_post(&mx_vel);
356
        kill_shot = 1;
357
}
358
 
359
void create_astro_task()
360
{
361
        HARD_TASK_MODEL mp;
362
        SOFT_TASK_MODEL ms;
363
        PID pid;
364
        int incr;
365
 
366
        soft_task_default_model(ms);
367
        soft_task_def_ctrl_jet(ms);
368
        soft_task_def_arg(ms, (void *)nshot);
369
        soft_task_def_met(ms, ASTRO_WCET);
370
        soft_task_def_period(ms,ASTRO_PERIOD);
371
        soft_task_def_usemath(ms);
372
        pid = task_create("Astro", astro, &ms, NULL);
373
        if (pid == NIL) {
1376 giacomo 374
                sys_shutdown_message("Could not create task <astro>\n");
1550 pj 375
                exit(1);
1162 tavani 376
        } else
377
                task_activate(pid);
378
 
379
        hard_task_default_model(mp);
380
        hard_task_def_ctrl_jet(mp);
381
        hard_task_def_wcet(mp,LOOK_WCET);
382
        hard_task_def_mit(mp, LOOK_PERIOD);
383
        hard_task_def_usemath(mp);
384
        pid = task_create("Taken", look, &mp, NULL);
385
        if (pid == NIL) {
1376 giacomo 386
                sys_shutdown_message("Could not create task <Taken>\n");
1550 pj 387
                exit(1);
1162 tavani 388
        } else
389
                task_activate(pid);
390
 
391
        incr = ASTRO_GRAD_INC;
392
        hard_task_default_model(mp);
393
        hard_task_def_ctrl_jet(mp);
394
        hard_task_def_arg(mp, (void *)incr);
395
        hard_task_def_wcet(mp,ASTRO_WCET);
396
        hard_task_def_mit(mp, ASTRO_MOVE_PERIOD);
397
        hard_task_def_aperiodic(mp);
398
        hard_task_def_usemath(mp);
399
        pid_TL = task_create("TurnLeft", turn, &mp, NULL);
400
        if (pid_TL == NIL) {
1376 giacomo 401
                sys_shutdown_message("Could not create task <Turn L>\n");
1550 pj 402
                exit(1);
1162 tavani 403
        }
404
 
405
        incr = - ASTRO_GRAD_INC;
406
        hard_task_default_model(mp);
407
        hard_task_def_ctrl_jet(mp);
408
        hard_task_def_arg(mp, (void *)incr);
409
        hard_task_def_wcet(mp,ASTRO_WCET);
410
        hard_task_def_mit(mp, ASTRO_MOVE_PERIOD);
411
        hard_task_def_aperiodic(mp);
412
        hard_task_def_usemath(mp);
413
        pid_TR = task_create("TurnRight", turn, &mp, NULL);
414
        if (pid_TR == NIL) {
1376 giacomo 415
                sys_shutdown_message("Could not create task <Turn R>\n");
1550 pj 416
                exit(1);
1162 tavani 417
        }
418
 
419
        incr = ASTRO_VEL_INC;
420
        hard_task_default_model(mp);
421
        hard_task_def_ctrl_jet(mp);
422
        hard_task_def_arg(mp, (void *)incr);
423
        hard_task_def_wcet(mp,ASTRO_WCET);
424
        hard_task_def_mit(mp, ASTRO_PERIOD);
425
        hard_task_def_aperiodic(mp);
426
        hard_task_def_usemath(mp);
427
        pid_SU = task_create("SpeedUP", speed, &mp, NULL);
428
        if (pid_SU == NIL) {
1376 giacomo 429
                sys_shutdown_message("Could not create task <Speed UP>\n");
1550 pj 430
                exit(1);
1162 tavani 431
        }
432
 
433
        incr = - ASTRO_VEL_INC;
434
        hard_task_default_model(mp);
435
        hard_task_def_ctrl_jet(mp);
436
        hard_task_def_arg(mp, (void *)incr);
437
        hard_task_def_wcet(mp,ASTRO_WCET);
438
        hard_task_def_mit(mp, ASTRO_PERIOD);
439
        hard_task_def_aperiodic(mp);
440
        hard_task_def_usemath(mp);
441
        pid_SD = task_create("SpeedDOWN", speed, &mp, NULL);
442
        if (pid_SD == NIL) {
1376 giacomo 443
                sys_shutdown_message("Could not create task <Speed DOWN>\n");
1550 pj 444
                exit(1);
1162 tavani 445
        }
446
 
447
        incr = 0;
448
        hard_task_default_model(mp);
449
        hard_task_def_ctrl_jet(mp);
450
        hard_task_def_arg(mp, (void *)incr);
451
        hard_task_def_wcet(mp,ASTRO_WCET);
452
        hard_task_def_mit(mp, ASTRO_PERIOD);
453
        hard_task_def_aperiodic(mp);
454
        hard_task_def_usemath(mp);
455
        pid_SZ = task_create("SpeedZERO", speed, &mp, NULL);
456
        if (pid_SZ == NIL) {
1376 giacomo 457
                sys_shutdown_message("Could not create task <Speed ZERO>\n");
1550 pj 458
                exit(1);
1162 tavani 459
        }
460
 
461
        hard_task_default_model(mp);
462
        hard_task_def_ctrl_jet(mp);
463
        hard_task_def_wcet(mp,ASTRO_WCET);
464
        hard_task_def_mit(mp, 6*ASTRO_PERIOD);
465
        hard_task_def_usemath(mp);
466
        pid = task_create("MoveAstro", move, &mp, NULL);
467
        if (pid == NIL) {
1376 giacomo 468
                sys_shutdown_message("Could not create task <MoveAstro>\n");
1550 pj 469
                exit(1);
1162 tavani 470
        } else
471
                task_activate(pid);
472
 
473
#ifdef ASTRO_MOVE
474
        incr = 0;
475
        hard_task_default_model(mp);
476
        hard_task_def_ctrl_jet(mp);
477
        hard_task_def_arg(mp, (void *)incr);
478
        hard_task_def_wcet(mp,ASTRO_WCET);
1535 giacomo 479
        hard_task_def_mit(mp, 3*ASTRO_PERIOD);
1162 tavani 480
        hard_task_def_aperiodic(mp);
481
        hard_task_def_usemath(mp);
482
        pid_FL = task_create("FlipAstro", turn, &mp, NULL);
483
        if (pid_FL == NIL) {
1376 giacomo 484
                sys_shutdown_message("Could not create task <Flip Astro>\n");
1550 pj 485
                exit(1);
1162 tavani 486
        }
487
#endif
488
}
489
 
490
void frame_astro()
491
{
492
        grx_text("Game", 10, 45, RGB_BLUE, RGB_BLACK);
493
        grx_line(GB_XMIN-2,55,GB_XMAX+2,55,RGB_RED);
494
 
495
        grx_rect(GB_XMIN-3, GB_YMIN-3, GB_XMAX+3, GB_YMAX+3, RGB_GREEN);
496
 
497
#ifndef ASTRO_MOVE
498
        grx_rect(GB_XMIN-1, GB_YMAX-1, GB_XMAX+1, GB_YMAX+1, RGB_CYAN);
499
#endif
500
}
501
 
502
void init_astro()
503
{
504
        KEY_EVT k;
505
 
506
        crash = 0;
507
        freez_astro = 1;
508
        kill_shot = 1;
509
        astro_vel  = 0;
510
        astro_grad = 0;
511
        astro_x = ASTRO_X;
512
        astro_y = ASTRO_Y;
513
 
514
        create_astro_task();
515
 
516
        k.flag = 0;
517
        k.scan = KEY_SPC;
518
        k.ascii = ' ';
1567 mauro 519
        k.status = KEY_PRESSED | KEY_REPEATED;
1349 giacomo 520
        keyb_hook(k,new_shot,FALSE);
1162 tavani 521
 
522
        k.flag = 0;
523
        k.scan = KEY_O;
524
        k.ascii = 'o';
1567 mauro 525
        k.status = KEY_PRESSED | KEY_REPEATED;
1349 giacomo 526
        keyb_hook(k,pad,FALSE);
1162 tavani 527
 
528
        k.flag = 0;
529
        k.scan = KEY_P;
530
        k.ascii = 'p';
1567 mauro 531
        k.status = KEY_PRESSED | KEY_REPEATED;
1349 giacomo 532
        keyb_hook(k,pad,FALSE);
1162 tavani 533
 
534
        k.flag = 0;
535
        k.scan = KEY_S;
536
        k.ascii = 's';
1567 mauro 537
        k.status = KEY_PRESSED | KEY_REPEATED;
1349 giacomo 538
        keyb_hook(k,pad,FALSE);
1162 tavani 539
 
540
        k.flag = 0;
541
        k.scan = KEY_Z;
542
        k.ascii = 'z';
1567 mauro 543
        k.status = KEY_PRESSED | KEY_REPEATED;
1349 giacomo 544
        keyb_hook(k,pad,FALSE);
1162 tavani 545
 
546
#ifdef ASTRO_MOVE
547
        k.flag = 0;
548
        k.scan = KEY_A;
549
        k.ascii = 'a';
1349 giacomo 550
        k.status = KEY_PRESSED;
551
        keyb_hook(k,pad,FALSE);
1162 tavani 552
 
553
        k.flag = 0;
554
        k.scan = KEY_F;
555
        k.ascii = 'f';
1349 giacomo 556
        k.status = KEY_PRESSED;
557
        keyb_hook(k,pad,FALSE);
1162 tavani 558
#else
559
        k.flag = 0;
560
        k.scan = KEY_X;
561
        k.ascii = 'x';
1349 giacomo 562
        k.status = KEY_PRESSED;
563
        keyb_hook(k,pad,FALSE);
1162 tavani 564
 
565
#endif
566
}