Subversion Repositories shark

Rev

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