Subversion Repositories shark

Rev

Rev 1162 | Rev 1351 | 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))) {
84
				draw_rock(rx, ry, rr, RGB_BLACK);
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_level(mp,1);
321
	soft_task_def_ctrl_jet(mp);
322
	soft_task_def_arg(mp, (void *)nshot);
323
	soft_task_def_group(mp, SHOT_GROUP);
324
	soft_task_def_met(mp, SHOT_WCET);
325
	soft_task_def_period(mp,SHOT_PERIOD);
326
	soft_task_def_usemath(mp);
327
	pid = task_create("Shot", shot, &mp, NULL);
328
 
329
	if (pid != NIL) {
330
		task_activate(pid);
331
		nshot++;
332
		sem_wait(&mx_st_nrg);
333
		energy -= ENERGY_SHOT;
334
		sem_post(&mx_st_nrg);
335
	}
336
}
337
 
338
void start_astro()
339
{
340
	freez_astro = 0;
341
	kill_shot = 0;
342
}
343
 
344
void reset_astro()
345
{
346
	freez_astro = 1;
347
	sem_wait(&mx_xy);
348
	astro_x = ASTRO_X;
349
	astro_y = ASTRO_Y;
350
	sem_post(&mx_xy);
351
	sem_wait(&mx_pos);
352
	astro_grad = 0;
353
	sem_post(&mx_pos);
354
	sem_wait(&mx_vel);
355
	astro_vel = 0;
356
	sem_post(&mx_vel);
357
	kill_shot = 1;
358
}
359
 
360
void create_astro_task()
361
{
362
	HARD_TASK_MODEL mp;
363
	SOFT_TASK_MODEL ms;
364
	PID pid;
365
	int incr;
366
 
367
	soft_task_default_model(ms);
368
	soft_task_def_level(ms,1);
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) {
1349 giacomo 376
		FB26_close(FRAME_BUFFER_DEVICE);
1162 tavani 377
		perror("Could not create task <astro>");
378
		sys_end();
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) {
1349 giacomo 389
		FB26_close(FRAME_BUFFER_DEVICE);
1162 tavani 390
		perror("Could not create task <Taken>");
391
		sys_end();
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) {
1349 giacomo 405
		FB26_close(FRAME_BUFFER_DEVICE);
1162 tavani 406
		perror("Could not create task <Turn L>");
407
		sys_end();
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) {
1349 giacomo 420
		FB26_close(FRAME_BUFFER_DEVICE);
1162 tavani 421
		perror("Could not create task <Turn R>");
422
		sys_end();
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) {
1349 giacomo 435
		FB26_close(FRAME_BUFFER_DEVICE);
1162 tavani 436
		perror("Could not create task <Speed UP>");
437
		sys_end();
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) {
1349 giacomo 450
		FB26_close(FRAME_BUFFER_DEVICE);
1162 tavani 451
		perror("Could not create task <Speed DOWN>");
452
		sys_end();
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) {
1349 giacomo 465
		FB26_close(FRAME_BUFFER_DEVICE);
1162 tavani 466
		perror("Could not create task <Speed ZERO>");
467
		sys_end();
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) {
1349 giacomo 477
		FB26_close(FRAME_BUFFER_DEVICE);
1162 tavani 478
		perror("Could not create task <MoveAstro>");
479
		sys_end();
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) {
1349 giacomo 494
		FB26_close(FRAME_BUFFER_DEVICE);
1162 tavani 495
		perror("Could not create task <Flip Astro>");
496
		sys_end();
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
}