Subversion Repositories shark

Rev

Rev 1376 | Rev 1392 | 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
 
1378 giacomo 27
extern PID shutdown_task_PID;
1373 giacomo 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) {
1376 giacomo 376
		sys_shutdown_message("Could not create task <astro>\n");
1378 giacomo 377
		task_activate(shutdown_task_PID);
1376 giacomo 378
		return;
1162 tavani 379
	} else
380
		task_activate(pid);
381
 
382
	hard_task_default_model(mp);
383
	hard_task_def_ctrl_jet(mp);
384
	hard_task_def_wcet(mp,LOOK_WCET);
385
	hard_task_def_mit(mp, LOOK_PERIOD);
386
	hard_task_def_usemath(mp);
387
	pid = task_create("Taken", look, &mp, NULL);
388
	if (pid == NIL) {
1376 giacomo 389
		sys_shutdown_message("Could not create task <Taken>\n");
1378 giacomo 390
		task_activate(shutdown_task_PID);
1376 giacomo 391
		return;
1162 tavani 392
	} else
393
		task_activate(pid);
394
 
395
	incr = ASTRO_GRAD_INC;
396
	hard_task_default_model(mp);
397
	hard_task_def_ctrl_jet(mp);
398
	hard_task_def_arg(mp, (void *)incr);
399
	hard_task_def_wcet(mp,ASTRO_WCET);
400
	hard_task_def_mit(mp, ASTRO_MOVE_PERIOD);
401
	hard_task_def_aperiodic(mp);
402
	hard_task_def_usemath(mp);
403
	pid_TL = task_create("TurnLeft", turn, &mp, NULL);
404
	if (pid_TL == NIL) {
1376 giacomo 405
		sys_shutdown_message("Could not create task <Turn L>\n");
1378 giacomo 406
		task_activate(shutdown_task_PID);
1376 giacomo 407
		return;
1162 tavani 408
	}
409
 
410
	incr = - ASTRO_GRAD_INC;
411
	hard_task_default_model(mp);
412
	hard_task_def_ctrl_jet(mp);
413
	hard_task_def_arg(mp, (void *)incr);
414
	hard_task_def_wcet(mp,ASTRO_WCET);
415
	hard_task_def_mit(mp, ASTRO_MOVE_PERIOD);
416
	hard_task_def_aperiodic(mp);
417
	hard_task_def_usemath(mp);
418
	pid_TR = task_create("TurnRight", turn, &mp, NULL);
419
	if (pid_TR == NIL) {
1376 giacomo 420
		sys_shutdown_message("Could not create task <Turn R>\n");
1378 giacomo 421
		task_activate(shutdown_task_PID);
1376 giacomo 422
		return;
1162 tavani 423
	}
424
 
425
	incr = ASTRO_VEL_INC;
426
	hard_task_default_model(mp);
427
	hard_task_def_ctrl_jet(mp);
428
	hard_task_def_arg(mp, (void *)incr);
429
	hard_task_def_wcet(mp,ASTRO_WCET);
430
	hard_task_def_mit(mp, ASTRO_PERIOD);
431
	hard_task_def_aperiodic(mp);
432
	hard_task_def_usemath(mp);
433
	pid_SU = task_create("SpeedUP", speed, &mp, NULL);
434
	if (pid_SU == NIL) {
1376 giacomo 435
		sys_shutdown_message("Could not create task <Speed UP>\n");
1378 giacomo 436
		task_activate(shutdown_task_PID);
1376 giacomo 437
		return;
1162 tavani 438
	}
439
 
440
	incr = - ASTRO_VEL_INC;
441
	hard_task_default_model(mp);
442
	hard_task_def_ctrl_jet(mp);
443
	hard_task_def_arg(mp, (void *)incr);
444
	hard_task_def_wcet(mp,ASTRO_WCET);
445
	hard_task_def_mit(mp, ASTRO_PERIOD);
446
	hard_task_def_aperiodic(mp);
447
	hard_task_def_usemath(mp);
448
	pid_SD = task_create("SpeedDOWN", speed, &mp, NULL);
449
	if (pid_SD == NIL) {
1376 giacomo 450
		sys_shutdown_message("Could not create task <Speed DOWN>\n");
1378 giacomo 451
		task_activate(shutdown_task_PID);
1376 giacomo 452
		return;
1162 tavani 453
	}
454
 
455
	incr = 0;
456
	hard_task_default_model(mp);
457
	hard_task_def_ctrl_jet(mp);
458
	hard_task_def_arg(mp, (void *)incr);
459
	hard_task_def_wcet(mp,ASTRO_WCET);
460
	hard_task_def_mit(mp, ASTRO_PERIOD);
461
	hard_task_def_aperiodic(mp);
462
	hard_task_def_usemath(mp);
463
	pid_SZ = task_create("SpeedZERO", speed, &mp, NULL);
464
	if (pid_SZ == NIL) {
1376 giacomo 465
		sys_shutdown_message("Could not create task <Speed ZERO>\n");
1378 giacomo 466
		task_activate(shutdown_task_PID);
1376 giacomo 467
		return;
1162 tavani 468
	}
469
 
470
	hard_task_default_model(mp);
471
	hard_task_def_ctrl_jet(mp);
472
	hard_task_def_wcet(mp,ASTRO_WCET);
473
	hard_task_def_mit(mp, 6*ASTRO_PERIOD);
474
	hard_task_def_usemath(mp);
475
	pid = task_create("MoveAstro", move, &mp, NULL);
476
	if (pid == NIL) {
1376 giacomo 477
		sys_shutdown_message("Could not create task <MoveAstro>\n");
1378 giacomo 478
		task_activate(shutdown_task_PID);
1376 giacomo 479
		return;
1162 tavani 480
	} else
481
		task_activate(pid);
482
 
483
#ifdef ASTRO_MOVE
484
	incr = 0;
485
	hard_task_default_model(mp);
486
	hard_task_def_ctrl_jet(mp);
487
	hard_task_def_arg(mp, (void *)incr);
488
	hard_task_def_wcet(mp,ASTRO_WCET);
489
	hard_task_def_mit(mp, ASTRO_PERIOD);
490
	hard_task_def_aperiodic(mp);
491
	hard_task_def_usemath(mp);
492
	pid_FL = task_create("FlipAstro", turn, &mp, NULL);
493
	if (pid_FL == NIL) {
1376 giacomo 494
		sys_shutdown_message("Could not create task <Flip Astro>\n");
1378 giacomo 495
		task_activate(shutdown_task_PID);
1376 giacomo 496
		return;
1162 tavani 497
	}
498
#endif
499
}
500
 
501
void frame_astro()
502
{
503
	grx_text("Game", 10, 45, RGB_BLUE, RGB_BLACK);
504
	grx_line(GB_XMIN-2,55,GB_XMAX+2,55,RGB_RED);
505
 
506
	grx_rect(GB_XMIN-3, GB_YMIN-3, GB_XMAX+3, GB_YMAX+3, RGB_GREEN);
507
 
508
#ifndef ASTRO_MOVE
509
	grx_rect(GB_XMIN-1, GB_YMAX-1, GB_XMAX+1, GB_YMAX+1, RGB_CYAN);
510
#endif
511
}
512
 
513
void init_astro()
514
{
515
	KEY_EVT k;
516
 
517
	crash = 0;
518
	freez_astro = 1;
519
	kill_shot = 1;
520
	astro_vel  = 0;
521
	astro_grad = 0;
522
	astro_x = ASTRO_X;
523
	astro_y = ASTRO_Y;
524
 
525
	create_astro_task();
526
 
527
	k.flag = 0;
528
	k.scan = KEY_SPC;
529
	k.ascii = ' ';
1349 giacomo 530
	k.status = KEY_PRESSED;
531
	keyb_hook(k,new_shot,FALSE);
1162 tavani 532
 
533
	k.flag = 0;
534
	k.scan = KEY_O;
535
	k.ascii = 'o';
1349 giacomo 536
	k.status = KEY_PRESSED;
537
	keyb_hook(k,pad,FALSE);
1162 tavani 538
 
539
	k.flag = 0;
540
	k.scan = KEY_P;
541
	k.ascii = 'p';
1349 giacomo 542
	k.status = KEY_PRESSED;
543
	keyb_hook(k,pad,FALSE);
1162 tavani 544
 
545
	k.flag = 0;
546
	k.scan = KEY_S;
547
	k.ascii = 's';
1349 giacomo 548
	k.status = KEY_PRESSED;
549
	keyb_hook(k,pad,FALSE);
1162 tavani 550
 
551
	k.flag = 0;
552
	k.scan = KEY_Z;
553
	k.ascii = 'z';
1349 giacomo 554
	k.status = KEY_PRESSED;
555
	keyb_hook(k,pad,FALSE);
1162 tavani 556
 
557
#ifdef ASTRO_MOVE
558
	k.flag = 0;
559
	k.scan = KEY_A;
560
	k.ascii = 'a';
1349 giacomo 561
	k.status = KEY_PRESSED;
562
	keyb_hook(k,pad,FALSE);
1162 tavani 563
 
564
	k.flag = 0;
565
	k.scan = KEY_F;
566
	k.ascii = 'f';
1349 giacomo 567
	k.status = KEY_PRESSED;
568
	keyb_hook(k,pad,FALSE);
1162 tavani 569
#else
570
	k.flag = 0;
571
	k.scan = KEY_X;
572
	k.ascii = 'x';
1349 giacomo 573
	k.status = KEY_PRESSED;
574
	keyb_hook(k,pad,FALSE);
1162 tavani 575
 
576
#endif
577
}