Subversion Repositories shark

Rev

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