Subversion Repositories shark

Rev

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