Subversion Repositories shark

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1171 giacomo 1
/*--------------------------------------------------------------*/
2
/*              BILIARDO: FILE CONTENENTE TASK PALLA E SCHEDULAZIONE             */
3
/*--------------------------------------------------------------*/
4
 
5
#include <kernel/func.h>
6
#include <stdlib.h>
7
#include <math.h>
8
#include "biliardo.h"
9
#include "posizion.h"
10
 
11
#define R 4   // dimensioni della palla
12
#define RB 7   // dimensioni della buca
13
#define COD_FRECCIA 64
14
 
15
static int ballexit[BALL_MAX_P]; // controllo eliminazione task palla
16
static int      npc = 0;        // numero dei task palla in gioco
17
struct  posizione PosPalla[BALL_MAX_P]; // posizione delle palle in gioco
18
int FlagPartita = 0;
19
int ch = 0, curs = 0;
20
int punteggio[2]; // punteggio relativo al giocatore
21
int giocatore = 0; // giocatore
22
int bForza;
23
 
24
 
25
TASK    palla(int i) {
26
 
27
  float oxf, oyf; // posizione precedente della palla
28
  int col;
29
 
30
  setPalla (i);
31
 
32
  mutex_lock(&palmutex);
33
  col = PosPalla[i].col;
34
  oxf = PosPalla[i].x;
35
  oyf = BALL_Y - PosPalla[i].y;
36
  mutex_unlock(&palmutex);
37
 
38
  mutex_lock(&mutex);
39
  grx_disc(oxf, oyf, R, col);
40
  grx_text("                      ",432,85, black, black);
41
  mutex_unlock(&mutex);
42
 
43
  while (1) {
44
 
45
      mutex_lock(&mutex);
46
      grx_disc(oxf, oyf, R, 0);
47
//      grx_line(oxf, oyf, oxf+vx, oyf-vy, 0);
48
      mutex_unlock(&mutex);
49
 
50
      mutex_lock(&palmutex);
51
      oxf = PosPalla[i].x;
52
      oyf = BALL_Y - PosPalla[i].y;
53
      mutex_unlock(&palmutex);
54
 
55
      mutex_lock (&delmutex);
56
      if (ballexit[i]) {
57
         npc--;
58
         mutex_unlock (&delmutex);
59
         return 0;
60
      }
61
      mutex_unlock (&delmutex);
62
 
63
      mutex_lock(&mutex);
64
      grx_disc(oxf, oyf, R, col);
65
//      grx_line(oxf, oyf, oxf+vx, oyf-vy, col);
66
           mutex_unlock(&mutex);
67
 
68
    task_endcycle();
69
  }
70
}
71
 
72
TASK sched() {
73
 
74
  int i, j;
75
  int k;
76
 
77
  char strTmp[21];
78
  struct  posizione posIn[BALL_MAX_P];
79
  struct  posizione posOut[BALL_MAX_P];
80
  struct posizione pos[BALL_MAX_P];
81
 
82
 
83
  int flag, bBevuta = 0;
84
  float dist = 0;
85
 
86
 
87
  float dx, dy; // variazione coordinate
88
  float dt;             /* incremento temporale         */
89
  float modx, mody;
90
 
91
  // angolo formato dalla retta passante per il baricentro delle palle in collisione
92
  float thetaB1 = 0, thetaB2 = 0;
93
  float tratto;    //tratto percorso
94
  float thetaO1, thetaO2;
95
 
96
  float attr = 0.0021; // attrito applicato ad ogni palla
97
  float acc;
98
  float g = 9.86; // forza di gravit… utilizzata per il calcolo dell'attrito
99
  float v0 = 0;
100
 
101
  float xCurs, yCurs;
102
  int bRiposiz = 1;
103
  int punteggio[2];
104
  int giocatore = 0;
105
  int sign;
106
  float v1x, v1y, v2x, v2y;
107
  float phi;
108
  float thetaV1, thetaV2;
109
  float thetaBarOld1, thetaBarOld2;
110
  // evita che venga segnalata pi— volte una collisione
111
  int flag1coll[BALL_MAX_P];
112
  // segna nella locazione di una palla con quale altra palla ha colliso
113
  int flagCollCorr[BALL_MAX_P];
114
  // ricorda per ogni palla quale Š stata la collisione precedente
115
  int flagCollPrec[BALL_MAX_P];
116
  int flagAgg[BALL_MAX_P];
117
  int flagAggNum[BALL_MAX_P];
118
 
119
  for (i=0; i<BALL_MAX_P; i++) {
120
      flagCollPrec[i] = -1;
121
  }
122
 
123
  dt = ((float)PERIOD_BALL)/40000;
124
 
125
  acc = attr * g;
126
 
127
  flag = 1;
128
  k = 0;
129
 
130
  while (1) {
131
   if (ch == 'i') {
132
      punteggio[0] = 0, punteggio[1] = 0;
133
      ch = 0;
134
   }
135
 
136
   if (FlagPartita) {
137
 
138
// inizio mutex
139
  mutex_lock(&palmutex);
140
 
141
   if (PosPalla[i].theta < 0)
142
      PosPalla[i].theta += 2*PI;
143
   else
144
      if (PosPalla[i].theta > 2*PI)
145
         PosPalla[i].theta -= 2*PI;
146
 
147
      for(i=0; i<BALL_MAX_P; i++) {
148
         flag1coll[i] = 0;
149
         flagCollCorr[i] = -1;
150
         flagAgg[i] = 0;
151
         posIn[i].x = posOut[i].x = PosPalla[i].x;
152
         posIn[i].y = posOut[i].y = PosPalla[i].y;
153
         posIn[i].v = posOut[i].v = PosPalla[i].v;
154
         posIn[i].theta = posOut[i].theta = PosPalla[i].theta;
155
 
156
 
157
      }
158
 
159
  mutex_unlock(&palmutex);
160
 
161
// fine mutex
162
 
163
    for(i=0; i<BALL_MAX_P; i++) {
164
 
165
      for(j=0; j<BALL_MAX_P; j++) {
166
 
167
         if (i < j && flagCollCorr[i] == -1) {
168
 
169
            if(posIn[i].x-R >= posIn[j].x-R && posIn[i].x-R <= posIn[j].x+R
170
                           && posIn[i].y-R >= posIn[j].y-R && posIn[i].y-R <= posIn[j].y+R) {
171
 
172
               flagCollCorr[i] = j;
173
               flagCollCorr[j] = i;
174
               break;
175
            }
176
           else
177
 
178
            if(posIn[i].x-R >= posIn[j].x-R && posIn[i].x-R <= posIn[j].x+R
179
            && posIn[i].y+R >= posIn[j].y-R && posIn[i].y+R <= posIn[j].y+R) {
180
 
181
               flagCollCorr[i] = j;
182
               flagCollCorr[j] = i;
183
               break;
184
            }
185
            else
186
 
187
               if(posIn[i].x+R >= posIn[j].x-R && posIn[i].x+R <= posIn[j].x+R
188
               && posIn[i].y+R >= posIn[j].y-R && posIn[i].y+R <= posIn[j].y+R) {
189
 
190
                  flagCollCorr[i] = j;
191
                  flagCollCorr[j] = i;
192
                  break;
193
               }
194
               else
195
 
196
                  if(posIn[i].x+R >= posIn[j].x-R && posIn[i].x+R <= posIn[j].x+R
197
                                 && posIn[i].y-R >= posIn[j].y-R && posIn[i].y-R <= posIn[j].y+R) {
198
 
199
                     flagCollCorr[i] = j;
200
                     flagCollCorr[j] = i;
201
                     break;
202
                  }
203
                  else {
204
                    flagCollCorr[i] = -1;
205
                    flagCollPrec[i] = -1;
206
                  }
207
 
208
 
209
        }      // fine if(i!=j)
210
      }        // fine ciclo for(j)
211
 
212
 
213
            if (flagCollCorr[i] != -1 && flagCollCorr[i] != flagCollPrec[i])  {
214
 
215
 
216
               dist = sqrt(pow(posIn[i].x - posIn[flagCollCorr[i]].x,2)
217
                    + pow(posIn[i].y - posIn[flagCollCorr[i]].y,2));
218
               if (dist < 2*R) {
219
                  flagAgg[i] = 1;
220
                  flagAgg[flagCollCorr[i]] = 1;
221
                  dist = ceil (2*R-dist);
222
                  if ((int)dist%2 != 0)
223
                     dist += 1;
224
                  flagAggNum[i] = (int)dist/2;
225
 
226
               }
227
 
228
                  // permette la sola collisione di due palle contemporaneamente
229
                  flag1coll[i] = 1;
230
 
231
               flagCollPrec[i] = flagCollCorr[i];
232
 
233
            }
234
 
235
    }          // fine ciclo for(i)
236
 
237
 
238
    for(i=0; i<BALL_MAX_P; i++) {   // inizio ciclo for calcolo collisioni
239
 
240
       if (flag1coll[i]) {
241
 
242
          if (flag1coll[0])
243
             bBevuta = 0;
244
 
245
 
246
 
247
          sign = 1;
248
          modx = posIn[i].x - posIn[flagCollCorr[i]].x;
249
          mody = posIn[i].y - posIn[flagCollCorr[i]].y;
250
          if (modx*mody < 0) sign = 0;
251
          if (modx < 0) modx = -modx;
252
          if (mody < 0) mody = -mody;
253
 
254
// prima palla
255
          if (posIn[i].x <= posIn[flagCollCorr[i]].x && posIn[i].y <= posIn[flagCollCorr[i]].y) {
256
             // angolo formato dalla retta passante per il baricentro delle due palle
257
             thetaB1 = atan (mody / modx);
258
 
259
             if (flagAgg[i]) {
260
                posOut[i].x -=flagAggNum[i], posOut[i].y -=flagAggNum[i];
261
                flagAgg[i] = 0;
262
             }
263
 
264
          }
265
          else
266
              if (posIn[i].x >= posIn[flagCollCorr[i]].x && posIn[i].y <= posIn[flagCollCorr[i]].y) {
267
                 thetaB1 = PI - atan (mody / modx);
268
 
269
                 if (flagAgg[i]) {
270
                    posOut[i].x +=flagAggNum[i], posOut[i].y -=flagAggNum[i];
271
                    flagAgg[i] = 0;
272
                 }
273
 
274
              }
275
              else
276
                  if (posIn[i].x >= posIn[flagCollCorr[i]].x && posIn[i].y >= posIn[flagCollCorr[i]].y) {
277
                     thetaB1 = PI + atan (mody / modx);
278
 
279
                     if (flagAgg[i]) {
280
                        posOut[i].x +=flagAggNum[i], posOut[i].y +=flagAggNum[i];
281
                        flagAgg[i] = 0;
282
                     }
283
 
284
                  }
285
                  else
286
                      if (posIn[i].x <= posIn[flagCollCorr[i]].x && posIn[i].y >= posIn[flagCollCorr[i]].y) {
287
                         thetaB1 = 2*PI - atan (mody / modx);
288
 
289
                         if (flagAgg[i]) {
290
                            posOut[i].x -=flagAggNum[i], posOut[i].y +=flagAggNum[i];
291
                            flagAgg[i] = 0;
292
                         }
293
 
294
                  }
295
 
296
          if (thetaB1 < 0)
297
             thetaB1 += 2*PI;
298
          else
299
             if (thetaB1 > 2*PI)
300
                thetaB1 -= 2*PI;
301
 
302
// seconda palla
303
          if (posIn[i].x >= posIn[flagCollCorr[i]].x && posIn[i].y >= posIn[flagCollCorr[i]].y) {
304
             // angolo formato dalla retta passante per il baricentro delle due palle
305
             thetaB2 = atan (mody / modx);
306
          }
307
          else
308
              if (posIn[i].x <= posIn[flagCollCorr[i]].x && posIn[i].y >= posIn[flagCollCorr[i]].y) {
309
                 thetaB2 = PI - atan (mody / modx);
310
              }
311
              else
312
                  if (posIn[i].x <= posIn[flagCollCorr[i]].x && posIn[i].y <= posIn[flagCollCorr[i]].y) {
313
                     thetaB2 = PI + atan (mody / modx);
314
                  }
315
                  else
316
                      if (posIn[i].x >= posIn[flagCollCorr[i]].x && posIn[i].y <= posIn[flagCollCorr[i]].y) {
317
                         thetaB2 = 2*PI - atan (mody / modx);
318
                  }
319
 
320
          if (thetaB2 < 0)
321
             thetaB2 += 2*PI;
322
          else
323
             if (thetaB2 > 2*PI)
324
                thetaB2 -= 2*PI;
325
 
326
 
327
 
328
 
329
// aggiorno gli angoli rispetto al nuovo sistema di riferimento della prima palla
330
// con 0 in thetaB1-PI/2
331
          posOut[i].theta = posIn[i].theta + PI/2 - thetaB1;
332
          if (posOut[i].theta < 0)
333
             posOut[i].theta += 2*PI;
334
          else
335
              if (posOut[i].theta > 2*PI)
336
                 posOut[i].theta -= 2*PI;
337
 
338
          thetaO1 = posOut[i].theta;
339
 
340
// stessa cosa per la seconda palla con 0 in thetaB2-PI/2
341
          posOut[flagCollCorr[i]].theta = posIn[flagCollCorr[i]].theta + PI/2 - thetaB2;
342
          if (posOut[flagCollCorr[i]].theta < 0)
343
             posOut[flagCollCorr[i]].theta += 2*PI;
344
          else
345
              if (posOut[flagCollCorr[i]].theta > 2*PI)
346
                 posOut[flagCollCorr[i]].theta -= 2*PI;
347
          thetaO2 = posOut[flagCollCorr[i]].theta;
348
 
349
 
350
 
351
          thetaBarOld1 = thetaB1;
352
          thetaBarOld2 = thetaB2;
353
          thetaB1 = PI/2;
354
          thetaB2 = PI/2;
355
 
356
 
357
 
358
 
359
// Ho l'angolo formato dalle due palle => aggiorno gli angoli rispetto
360
// al nuovo sistema di riferimento
361
 
362
 
363
 
364
          if (cos(posOut[i].theta) <= 0)
365
             thetaV1 = PI - posOut[i].theta;
366
          else
367
              thetaV1 = -posOut[i].theta;
368
          if (thetaV1 < 0)
369
             thetaV1 = -thetaV1;
370
 
371
 
372
          if (cos(posOut[flagCollCorr[i]].theta) <= 0)
373
             thetaV2 = PI - posOut[flagCollCorr[i]].theta;
374
          else
375
              thetaV2 = -posOut[flagCollCorr[i]].theta;
376
          if (thetaV2 < 0)
377
             thetaV2 = -thetaV2;
378
 
379
 
380
 
381
          v1x = posIn[i].v * pow(cos(thetaV1), 2);
382
          v1y = posIn[i].v * pow(sin(thetaV1), 2);
383
          v2x = posIn[flagCollCorr[i]].v * pow(cos(thetaV2), 2);
384
          v2y = posIn[flagCollCorr[i]].v * pow(sin(thetaV2), 2);
385
 
386
// aggiusto i segni secondo il sistema della prima palla
387
          if (cos(posOut[i].theta) < 0)
388
             v1x = -v1x;
389
          if (sin(posOut[i].theta) < 0)
390
             v1y = -v1y;
391
          if (cos(posOut[flagCollCorr[i]].theta) > 0)
392
             v2x = -v2x;
393
          if (sin(posOut[flagCollCorr[i]].theta) > 0)
394
             v2y = -v2y;
395
 
396
          if (!v1y && v2y > 0) {
397
             v2y = 0;
398
          }
399
 
400
          if (v1y < 0 && v1y < v2y) {
401
             v2y = v1y;
402
 
403
          }
404
 
405
 
406
          // nuovo modulo della velocit… della palla 1
407
          posOut[i].v = sqrt(pow(v1x, 2) + pow(v2y, 2));
408
 
409
 
410
          if (v1x) {
411
             phi = atan (v2y / v1x);
412
             if (phi < 0)
413
                phi = -phi;
414
             }
415
          else
416
              phi = PI/2;
417
 
418
          if (v1x >= 0 && v2y >= 0) {
419
             // primo quadrante
420
                phi = phi;
421
          }
422
          else
423
              if (v1x <= 0 && v2y >= 0) {
424
                 // secondo quadrante
425
                    phi = PI/2 + (PI/2-phi);
426
              }
427
              else
428
                  if (v1x <= 0 && v2y <= 0)
429
                     // terzo quadrante
430
                     phi = PI + phi;
431
                  else
432
                      if (v1x >= 0 && v2y <= 0)
433
                         // quarto quadrante
434
                         phi = 3*PI/2 + (PI/2-phi);
435
 
436
          posOut[i].theta = phi;
437
 
438
 
439
          if (posOut[i].theta > 2*PI )
440
             posOut[i].theta = posOut[i].theta - 2*PI;
441
          else
442
             posOut[i].theta = posOut[i].theta;
443
 
444
 
445
 
446
// riporto tutto nel sistema di riferimento iniziale
447
          posOut[i].theta += -PI/2 + thetaBarOld1;
448
          if (posOut[i].theta < 0)
449
             posOut[i].theta += 2*PI;
450
          else
451
              if (posOut[i].theta > 2*PI)
452
                 posOut[i].theta -= 2*PI;
453
          posOut[flagCollCorr[i]].theta += (-PI/2 + thetaBarOld2);
454
          if (posOut[flagCollCorr[i]].theta < 0)
455
             posOut[flagCollCorr[i]].theta += 2*PI;
456
          else
457
              if (posOut[flagCollCorr[i]].theta > 2*PI)
458
                 posOut[flagCollCorr[i]].theta -= 2*PI;
459
 
460
 
461
 
462
 
463
          thetaB1 = thetaBarOld1;
464
          thetaB2 = thetaBarOld2;
465
 
466
 
467
/*               if (flag2 < 4) {
468
 
469
                  itoa (i, strTmp);
470
                  grx_text(strTmp,322,185+flag2*22, gray, black );
471
                  itoa (flagCollCorr[i], strTmp);
472
                  grx_text(strTmp,322,195+flag2*22, gray, black );
473
 
474
                  sprintf (strTmp, "%f", posIn[i].theta*360/(2*PI));
475
                  grx_text(strTmp,342,185+flag2*22, gray, black );
476
                  sprintf (strTmp, "%f", posIn[flagCollCorr[i]].theta*360/(2*PI));
477
                  grx_text(strTmp,342,195+flag2*22, gray, black );
478
 
479
                  sprintf (strTmp, "%f", posOut[i].theta*360/(2*PI));
480
                  grx_text(strTmp,432,185+flag2*22, gray, black );
481
                  sprintf (strTmp, "%f", posOut[flagCollCorr[i]].theta*360/(2*PI));
482
                  grx_text(strTmp,432,195+flag2*22, gray, black );
483
 
484
                  sprintf (strTmp, "%f", thetaB1*360/(2*PI));
485
                  grx_text(strTmp,522,185+flag2*22, gray, black );
486
                  sprintf (strTmp, "%f", thetaB2*360/(2*PI));
487
                  grx_text(strTmp,522,195+flag2*22, gray, black );
488
//       -----------------------
489
                  sprintf (strTmp, "%f", posIn[i].v);
490
                  grx_text(strTmp,322,290+flag2*22, gray, black );
491
                  sprintf (strTmp, "%f", posIn[flagCollCorr[i]].v);
492
                  grx_text(strTmp,322,300+flag2*22, gray, black );
493
 
494
                  sprintf (strTmp, "%f", v1x);
495
                  grx_text(strTmp,412,290+flag2*22, gray, black );
496
                  sprintf (strTmp, "%f", v2x);
497
                  grx_text(strTmp,412,300+flag2*22, gray, black );
498
 
499
                  sprintf (strTmp, "%f", v1y);
500
                  grx_text(strTmp,502,290+flag2*22, gray, black );
501
                  sprintf (strTmp, "%f", v2y);
502
                  grx_text(strTmp,502,300+flag2*22, gray, black );
503
 
504
                  sprintf (strTmp, "%f", posOut[i].v);
505
                  grx_text(strTmp,582,290+flag2*22, gray, black );
506
                  sprintf (strTmp, "%f", posOut[flagCollCorr[i]].v);
507
                  grx_text(strTmp,582,300+flag2*22, gray, black );
508
//       -----------------------
509
                  sprintf (strTmp, "%f", thetaV1*360/(2*PI));
510
                  grx_text(strTmp,322,390+flag2*22, gray, black );
511
                  sprintf (strTmp, "%f", thetaV2*360/(2*PI));
512
                  grx_text(strTmp,322,400+flag2*22, gray, black );
513
 
514
                  sprintf (strTmp, "%f", thetaO1*360/(2*PI));
515
                  grx_text(strTmp,402,390+flag2*22, gray, black );
516
                  sprintf (strTmp, "%f", thetaO2*360/(2*PI));
517
                  grx_text(strTmp,412,400+flag2*22, gray, black );
518
 
519
                  flag2++;
520
               }
521
*/
522
 
523
       } // fine if flag1coll
524
 
525
 
526
 
527
 
528
 
529
       // questo if fa i conti del movimento di ogni pallina
530
               if(posOut[i].v > 0) {
531
 
532
                  posOut[i].v -= acc * dt;
533
 
534
                  tratto = posOut[i].v * dt -0.5*acc*dt*dt;
535
 
536
                  dx = (float) (tratto * cos(posOut[i].theta));
537
                  dy = (float) (tratto * sin(posOut[i].theta));
538
 
539
                  posOut[i].x += dx;
540
                  posOut[i].y += dy;
541
 
542
 
543
 
544
                       if (posOut[i].x > BALL_XMAX) {
545
                               posOut[i].x = BALL_XMAX;
546
                               posOut[i].theta = PI - posOut[i].theta;
547
                  }
548
 
549
                       if (posOut[i].x < BALL_XMIN) {
550
                               posOut[i].x = BALL_XMIN;
551
                               posOut[i].theta = PI - posOut[i].theta;
552
                  }
553
 
554
                  if (posOut[i].y > BALL_YMAX) {
555
                     posOut[i].y = BALL_YMAX;
556
                     posOut[i].theta =  -posOut[i].theta;
557
                  }
558
 
559
                  if (posOut[i].y < 0) {
560
                     posOut[i].y = 0;
561
                     posOut[i].theta = -posOut[i].theta;
562
                  }
563
               }
564
 
565
         pos[i].x = posOut[i].x;
566
         pos[i].y = posOut[i].y;
567
         pos[i].v = posOut[i].v;
568
         pos[i].theta = posOut[i].theta;
569
 
570
    }  //fine ciclo for calcolo collisioni
571
 
572
   if (!pos[0].v && !pos[1].v && !pos[2].v && !pos[3].v && !pos[4].v && !pos[5].v &&
573
      !pos[6].v && !pos[7].v && !pos[8].v && !pos[9].v && !pos[10].v) {
574
 
575
      for (i=0; i<BALL_MAX_P; i++) {
576
          flagCollPrec[i] = -1;
577
      }
578
 
579
   }
580
 
581
   if (bRiposiz && flag) {
582
      mutex_lock(&mutex);
583
      grx_text("Modo riposizionamento palla bianca",322,85, white, black);
584
      mutex_unlock(&mutex);
585
      flag = 0;
586
   }
587
 
588
// posizionamento palla 0
589
    if (bRiposiz && curs) {
590
       if (curs == 77 && pos[0].x+R/2 <= BALL_XMAX) pos[0].x += 3;
591
       if (curs == 75 && pos[0].x-R >= BALL_XMIN) pos[0].x -= 3;
592
       curs = 0;
593
    }
594
 
595
// entra in modalit… calibrazione forza
596
    if (ch == ' ' && !bForza && (!pos[0].v && !pos[1].v && !pos[2].v
597
       && !pos[3].v && !pos[4].v && !pos[5].v && !pos[6].v &&
598
       !pos[7].v && !pos[8].v && !pos[9].v && !pos[10].v)) {
599
 
600
       bForza = 1;
601
       ch = 0, v0 = 3.5;
602
       xCurs = pos[0].x, yCurs = BALL_Y-pos[0].y+10;
603
       if (yCurs >= BALL_Y) yCurs = BALL_Y-pos[0].y;
604
 
605
            mutex_lock(&mutex);
606
       grx_text("Modo riposizionamento palla bianca",322,85, black, black);
607
       grx_text("Modo calibrazione forza",322,85, white, black);
608
       grx_text("Forza: ",322,95, white, black);
609
       sprintf (strTmp, "%2f", v0);
610
       grx_text(strTmp,402,95, red, black);
611
       grx_line(xCurs-2, yCurs, xCurs+2, yCurs, red);
612
       grx_line(xCurs, yCurs+2, xCurs, yCurs-2, red);
613
            mutex_unlock(&mutex);
614
 
615
       bRiposiz = 0;
616
    }
617
 
618
// calibrazione forza
619
    if (ch == 'a' && bForza) {
620
       if (v0 < 7.5)
621
          v0 += 0.3;
622
       if (v0 > 7.5)
623
          v0 = 7.5;
624
       ch = 0;
625
 
626
       mutex_lock(&mutex);
627
       grx_text("    ",402,95, black, black);
628
       sprintf (strTmp, "%2f", v0);
629
       grx_text(strTmp,402,95, red, black);
630
       mutex_unlock(&mutex);
631
    }
632
    else
633
        if (ch == 'z' && bForza) {
634
           if (v0 > 0)
635
              v0 -= 0.1;
636
           if (v0 < 0)
637
              v0 = 0;
638
           ch = 0;
639
 
640
           mutex_lock(&mutex);
641
           grx_text("    ",402,95, black, black);
642
           sprintf (strTmp, "%2f", v0);
643
           grx_text(strTmp,402,95, red, black);
644
           mutex_unlock(&mutex);
645
 
646
        }
647
 
648
// aggiusta il mirino
649
    if (bForza && curs) {
650
       mutex_lock(&mutex);
651
       grx_line(xCurs-2, yCurs, xCurs+2, yCurs, black);
652
       grx_line(xCurs, yCurs+2, xCurs, yCurs-2, black);
653
       if (curs == 72 && yCurs >= BALL_Y-BALL_YMAX-1) yCurs -= 2;
654
       if (curs == 80 && yCurs <= BALL_Y) yCurs += 2;
655
       if (curs == 77 && xCurs <= BALL_XMAX) xCurs += 2;
656
       if (curs == 75 && xCurs >= BALL_XMIN) xCurs -= 2;
657
       grx_line(xCurs-2, yCurs, xCurs+2, yCurs, red);
658
       grx_line(xCurs, yCurs+2, xCurs, yCurs-2, red);
659
       mutex_unlock(&mutex);
660
       curs = 0;
661
       bRiposiz = 0;
662
 
663
    }
664
 
665
// bevuta
666
    if (!pos[0].v && bBevuta) {
667
       pos[0].x = BALL_XMIN+100;
668
       pos[0].y = 50;
669
       pos[0].v = 0;
670
       pos[0].theta = 0;
671
       bRiposiz = 1;
672
       flag = 1;
673
       if (giocatore)
674
          giocatore = 0;
675
       else
676
           giocatore = 1;
677
       bBevuta = 0;
678
       mutex_lock(&mutex);
679
       grx_text("Modo riposizionamento palla bianca",322,85, white, black);
680
       mutex_unlock(&mutex);
681
 
682
    }
683
 
684
// scocca il colpo di stecca
685
    if (bForza && ch == ' ') {
686
 
687
//       mutex_lock(&palmutex);
688
       pos[0].v = v0;
689
       if (pos[0].x-xCurs)
690
          pos[0].theta = atan ((BALL_Y-pos[0].y-yCurs)/(pos[0].x-xCurs));
691
       else
692
           pos[0].theta = PI/2;
693
 
694
       if (pos[0].theta <0)
695
          pos[0].theta = -pos[0].theta;
696
 
697
       if (xCurs <= pos[0].x && yCurs >= BALL_Y-pos[0].y)
698
          // primo quadrante
699
          pos[0].theta = pos[0].theta;
700
       else
701
           if (xCurs >= pos[0].x && yCurs >= BALL_Y-pos[0].y)
702
              // secondo quadrante
703
              pos[0].theta = PI/2 + (PI/2-pos[0].theta);
704
           else
705
               if (xCurs >= pos[0].x && yCurs <= BALL_Y-pos[0].y)
706
                  // terzo quadrante
707
                  pos[0].theta = PI + pos[0].theta;
708
               else
709
                   if (xCurs <= pos[0].x && yCurs <= BALL_Y-pos[0].y)
710
                   // quarto quadrante
711
                   pos[0].theta = 3*PI/2 + (PI/2-pos[0].theta);
712
 
713
 
714
//       mutex_unlock(&palmutex);
715
       mutex_lock(&mutex);
716
       grx_line(xCurs-2, yCurs, xCurs+2, yCurs, black);
717
       grx_line(xCurs, yCurs+2, xCurs, yCurs-2, black);
718
       grx_text("Modo calibrazione forza",322,85, black, black);
719
       grx_text("Forza: ",322,95, black, black);
720
       grx_text("    ",402,95, black, black);
721
       mutex_unlock(&mutex);
722
       ch = bForza = 0;
723
       v0 = 0;
724
       bBevuta = 1;
725
    }
726
 
727
    if (ch == 'x') {
728
       for (i=0; i<BALL_MAX_P; i++) {
729
           flagCollPrec[i] = -1;
730
       }
731
       ch = 0;
732
 
733
    }
734
 
735
    itoa (giocatore, strTmp);
736
    mutex_lock(&mutex);
737
    grx_text(strTmp,432,110, red, black );
738
    itoa (punteggio[giocatore], strTmp);
739
    grx_text(strTmp,432,120, red, black );
740
    mutex_unlock(&mutex);
741
 
742
 
743
// aggiornamento della posizione delle palle
744
  mutex_lock(&palmutex);
745
 
746
      for (i=0; i<BALL_MAX_P; i++) {
747
         if (controlloBuche (pos[i].x, pos[i].y, i)) {
748
 
749
            if (i) {
750
               pos[i].x = -10;
751
               pos[i].y = 30;
752
               pos[i].v = 0;
753
               pos[i].theta = 0;
754
               punteggio[giocatore]++;
755
//                     itoa (npc, strTmp);
756
//                     grx_text(strTmp,322,285, black, red );
757
               if (punteggio[giocatore] >= 5) {
758
 
759
                  itoa (punteggio[giocatore], strTmp);
760
 
761
                  if (punteggio[giocatore] > 5) {
762
                     mutex_lock(&mutex);
763
                     grx_text(strTmp,432,120, red, black );
764
                     grx_text("Vittoria giocatore:",432,85, red, black);
765
                     itoa (giocatore, strTmp);
766
                     grx_text(strTmp,592,85, red, black );
767
                     mutex_unlock(&mutex);
768
                     killball ();
769
                  }
770
                  if (punteggio[giocatore] == 5 && npc == 2) {
771
                     mutex_lock(&mutex);
772
                     grx_text(strTmp,432,120, red, black );
773
                     grx_text("Pareggio",432,85, red, black);
774
                     mutex_unlock(&mutex);
775
                     killball ();
776
                  }
777
               }
778
            }
779
            else {
780
               pos[i].x = BALL_XMIN+100;
781
               pos[i].y = 50;
782
               pos[i].v = 0;
783
               pos[i].theta = 0;
784
 
785
               mutex_lock (&delmutex);
786
               ballexit[i] = 0;
787
               mutex_unlock (&delmutex);
788
 
789
               bRiposiz = 1;
790
               flag = 1;
791
               if (giocatore)
792
                  giocatore = 0;
793
               else
794
                  giocatore = 1;
795
               bBevuta = 0;
796
 
797
            }
798
         }
799
 
800
         PosPalla[i].x = pos[i].x;
801
         PosPalla[i].y = pos[i].y;
802
         if (pos[i].v >= 0) {
803
            PosPalla[i].v = pos[i].v;
804
            if (pos[i].theta > 2*PI )
805
               PosPalla[i].theta = pos[i].theta - 2*PI;
806
            else
807
                if (pos[i].theta < 0 )
808
                   PosPalla[i].theta = pos[i].theta + 2*PI;
809
                else
810
                    PosPalla[i].theta = pos[i].theta;
811
         }
812
         else {
813
            PosPalla[i].v = 0;
814
            PosPalla[i].theta = 0;
815
         }
816
      }
817
 
818
  mutex_unlock(&palmutex);
819
 
820
 
821
   }
822
   else {
823
        bRiposiz = 1, flag = 1;
824
        bBevuta = 0;
825
   }
826
 
827
      task_endcycle();
828
  }                 // fine ciclo while esterno
829
 
830
}
831
 
832
void inizioPartita () {
833
   if (!FlagPartita) {
834
      hardball();
835
      giocatore = 0;
836
      punteggio[0] = 0;
837
      punteggio[1] = 0;
838
      FlagPartita = 1;
839
   }
840
}
841
 
842
 
843
void killball() {
844
   int i;
845
 
846
   bForza = 0;
847
   mutex_lock (&delmutex);
848
   for (i=0; i<BALL_MAX_P; i++)
849
       ballexit[i] = 1;
850
   mutex_unlock (&delmutex);
851
   FlagPartita = 0;
852
}
853
 
854
 
855
void assegnaForza(KEY_EVT *k) {
856
      ch = k->ascii;
857
}
858
 
859
void movCursore (KEY_EVT *k) {
860
     curs = k->ascii;
861
}
862
 
863
/*
864
void ballfun(KEY_EVT *k)
865
{
866
  SOFT_TASK_MODEL mp;
867
  int r,g,b;
868
  PID pid;
869
  char palla_str[]="palla  ";
870
 
871
  soft_task_default_model(mp);
872
  soft_task_def_level(mp,1);
873
  soft_task_def_ctrl_jet(mp);
874
  soft_task_def_arg(mp);
875
  soft_task_def_group(mp, BALL_GROUP);
876
  soft_task_def_met(mp, WCET_BALL);
877
  soft_task_def_period(mp,PERIOD_BALL);
878
  soft_task_def_usemath(mp);
879
  pid = task_create(palla_str, palla, &mp, NULL);
880
 
881
  if (pid != NIL) {
882
    task_activate(pid);
883
  }
884
}
885
*/
886
 
887
// avvio dei task palla
888
void hardball()
889
{
890
   HARD_TASK_MODEL mp;
891
 
892
   PID pid;
893
   char pallaStr[]="palla   ";
894
   int i;
895
 
896
   if (npc == BALL_MAX_P) return;
897
 
898
   for(i=0;i<BALL_MAX_P;i++) {
899
 
900
      ballexit[i] = 0;
901
 
902
      itoa(i,pallaStr+6);
903
 
904
      hard_task_default_model(mp);
905
      hard_task_def_ctrl_jet(mp);
906
      hard_task_def_arg(mp, (void *)i);
907
      hard_task_def_wcet(mp, WCET_BALL);
908
      hard_task_def_mit(mp,PERIOD_BALL);
909
      hard_task_def_group(mp, BALL_GROUP);
910
      hard_task_def_usemath(mp);
911
      pid = task_create(pallaStr, palla, &mp, NULL);
912
 
913
      if (pid == NIL) {
914
         grx_close();
915
         perror("Could not create task <pallaEDF>");
916
              sys_end();
917
      }
918
      else {
919
         npc++;
920
      }
921
   }
922
   group_activate (BALL_GROUP);
923
}
924
 
925
// avvio del task di contollo
926
void hardSched()
927
{
928
  HARD_TASK_MODEL mp;
929
 
930
  PID pid;
931
 
932
  hard_task_default_model(mp);
933
  hard_task_def_ctrl_jet(mp);
934
//  hard_task_def_arg(mp, (void *)1);
935
  hard_task_def_wcet(mp, WCET_SCHED);
936
  hard_task_def_mit(mp, PERIOD_SCHED);
937
  hard_task_def_usemath(mp);
938
  pid = task_create("Schedular", sched, &mp, NULL);
939
  if (pid == NIL) {
940
        grx_close();
941
        perror("Could not create task <Schedulatore>");
942
        sys_end();
943
  }
944
  else
945
    task_activate(pid);
946
}
947
 
948
 
949
 
950
/*--------------------------------------------------------------*/
951
/*                      MAIN process                            */
952
/*--------------------------------------------------------------*/
953
 
954
void scenario_ball()
955
{
956
  int i;
957
 
958
 
959
//  Margine dello schermo
960
  grx_rect(0, 0, 639, 479, red);
961
 
962
  grx_line(320,78,639,78,red);
963
  grx_line(320,0,320,479,red);
964
 
965
//  Tavolo da biliardo
966
  grx_rect(60,30,260,430,lime);
967
  for (i=1; i<27; i++) {
968
        grx_rect(60-i,30-i,260+i,430+i,brown);
969
  }
970
 
971
// buche del tavolo
972
  grx_disc(62, 32, RB, black);
973
  grx_disc(258, 32, RB, black);
974
  grx_disc(62, 230, RB, black);
975
  grx_disc(258, 230, RB, black);
976
  grx_disc(62, 428, RB, black);
977
  grx_disc(258, 428, RB, black);
978
 
979
  grx_line(320,105,639,105,red);
980
  grx_line(320,130,639,130,red);
981
  grx_text("Giocatore:" ,322,110, red, black );
982
  grx_text("Punteggio:" ,322,120, red, black );
983
 
984
}
985
 
986
void init_ball(void)
987
{
988
    KEY_EVT k;
989
 
990
    k.flag = 0;
991
    k.scan = KEY_I;
992
    k.ascii = 'i';
993
    keyb_hook(k,assegnaForza);
994
    keyb_hook(k,inizioPartita);
995
 
996
 
997
/*  intercetta il tasto 'spazio' per passare in modo posizionamento
998
    e modo forza, mi serve per dare un colpo di stecca  */
999
 
1000
    k.flag = 0;
1001
    k.scan = KEY_SPC;
1002
    k.ascii = ' ';
1003
    keyb_hook(k,assegnaForza);
1004
 
1005
//  inizia una nuova partita
1006
    k.flag = 0;
1007
    k.scan = KEY_BKS;
1008
    k.ascii = ' ';
1009
    keyb_hook(k,killball);
1010
 
1011
    k.flag = 0;
1012
    k.scan = KEY_X;
1013
    k.ascii = 'x';
1014
    keyb_hook(k,assegnaForza);
1015
 
1016
 
1017
    k.flag = 0;
1018
    k.scan = KEY_A;
1019
    k.ascii = 'a';
1020
    keyb_hook(k,assegnaForza);
1021
 
1022
    k.flag = 0;
1023
    k.scan = KEY_Z;
1024
    k.ascii = 'z';
1025
    keyb_hook(k,assegnaForza);
1026
 
1027
    k.flag = COD_FRECCIA;
1028
    k.scan = 72;
1029
    k.ascii = 72;
1030
    keyb_hook(k,movCursore);
1031
 
1032
    k.flag = COD_FRECCIA;
1033
    k.scan = 75;
1034
    k.ascii = 75;
1035
    keyb_hook(k,movCursore);
1036
 
1037
    k.flag = COD_FRECCIA;
1038
    k.scan = 77;
1039
    k.ascii = 77;
1040
    keyb_hook(k,movCursore);
1041
 
1042
    k.flag = COD_FRECCIA;
1043
    k.scan = 80;
1044
    k.ascii = 80;
1045
    keyb_hook(k,movCursore);
1046
 
1047
}
1048
 
1049
// inizializzzazione task di schedulazione
1050
void initSched(void) {
1051
 
1052
  hardSched();
1053
}
1054
 
1055
// inizializzazione delle posizioni delle palle
1056
void setPalla (int num) {
1057
 
1058
  int nPalla = num;
1059
 
1060
  nPalla++;
1061
 
1062
  switch(nPalla) {
1063
    case 1:
1064
                        PosPalla[nPalla-1].x = BALL_XMIN + 100;
1065
                        PosPalla[nPalla-1].y = 50;
1066
         PosPalla[nPalla-1].v = 0;
1067
         PosPalla[nPalla-1].theta = 0;
1068
         PosPalla[nPalla-1].col = white;
1069
    break;
1070
    case 2:
1071
                        PosPalla[nPalla-1].x = BALL_XMIN + 100;
1072
                        PosPalla[nPalla-1].y = 300;
1073
         PosPalla[nPalla-1].v = 0;
1074
         PosPalla[nPalla-1].theta = 0;
1075
         PosPalla[nPalla-1].col = green;
1076
    break;
1077
    case 3:
1078
                        PosPalla[nPalla-1].x = BALL_XMIN + 90;
1079
                        PosPalla[nPalla-1].y = 310;
1080
         PosPalla[nPalla-1].v = 0;
1081
         PosPalla[nPalla-1].theta = 0;
1082
         PosPalla[nPalla-1].col = green;
1083
    break;
1084
    case 4:
1085
                        PosPalla[nPalla-1].x = BALL_XMIN + 110;
1086
                        PosPalla[nPalla-1].y = 310;
1087
         PosPalla[nPalla-1].v = 0;
1088
         PosPalla[nPalla-1].theta = 0;
1089
         PosPalla[nPalla-1].col = green;
1090
    break;
1091
    case 5:
1092
                        PosPalla[nPalla-1].x = BALL_XMIN + 80;
1093
                        PosPalla[nPalla-1].y = 320;
1094
         PosPalla[nPalla-1].v = 0;
1095
         PosPalla[nPalla-1].theta = 0;
1096
         PosPalla[nPalla-1].col = green;
1097
    break;
1098
    case 6:
1099
                        PosPalla[nPalla-1].x = BALL_XMIN + 100;
1100
                        PosPalla[nPalla-1].y = 320;
1101
         PosPalla[nPalla-1].v = 0;
1102
         PosPalla[nPalla-1].theta = 0;
1103
         PosPalla[nPalla-1].col = green;
1104
    break;
1105
    case 7:
1106
                        PosPalla[nPalla-1].x = BALL_XMIN + 120;
1107
                        PosPalla[nPalla-1].y = 320;
1108
         PosPalla[nPalla-1].v = 0;
1109
         PosPalla[nPalla-1].theta = 0;
1110
         PosPalla[nPalla-1].col = green;
1111
    break;
1112
    case 8:
1113
                        PosPalla[nPalla-1].x = BALL_XMIN + 70;
1114
                        PosPalla[nPalla-1].y = 330;
1115
         PosPalla[nPalla-1].v = 0;
1116
         PosPalla[nPalla-1].theta = 0;
1117
         PosPalla[nPalla-1].col = green;
1118
    break;
1119
    case 9:
1120
                        PosPalla[nPalla-1].x = BALL_XMIN + 90;
1121
                        PosPalla[nPalla-1].y = 330;
1122
         PosPalla[nPalla-1].v = 0;
1123
         PosPalla[nPalla-1].theta = 0;
1124
         PosPalla[nPalla-1].col = green;
1125
    break;
1126
    case 10:
1127
                        PosPalla[nPalla-1].x = BALL_XMIN + 110;
1128
                        PosPalla[nPalla-1].y = 330;
1129
         PosPalla[nPalla-1].v = 0;
1130
         PosPalla[nPalla-1].theta = 0;
1131
         PosPalla[nPalla-1].col = green;
1132
    break;
1133
    case 11:
1134
                        PosPalla[nPalla-1].x = BALL_XMIN + 130;
1135
                        PosPalla[nPalla-1].y = 330;
1136
         PosPalla[nPalla-1].v = 0;
1137
         PosPalla[nPalla-1].theta = 0;
1138
         PosPalla[nPalla-1].col = green;
1139
    break;
1140
    default:
1141
                        PosPalla[nPalla-1].x = BALL_XMIN;
1142
                        PosPalla[nPalla-1].y = 0;
1143
         PosPalla[nPalla-1].v = 0;
1144
         PosPalla[nPalla-1].theta = 0;
1145
         PosPalla[nPalla-1].col = green;
1146
    break;
1147
  }
1148
 
1149
}
1150
 
1151
// controllo quando una palla finisce in buca
1152
int controlloBuche (float x, float yRel, int i) {
1153
 
1154
   float y;
1155
 
1156
   y = BALL_Y - yRel;
1157
   if ((x <= 62+RB && y <= 32+RB) || (x >= 258-RB && y <= 32+RB) ||
1158
      (x <= 62+RB && (y >= 230-RB && y <= 230+RB)) || (x >= 258-RB && (y >= 230-RB && y <= 230+RB)) ||
1159
      (x <= 62+RB && y >= 428-RB) || (x >= 258-RB && y >= 428-RB)){
1160
 
1161
      // palla in buca
1162
      mutex_lock (&delmutex);
1163
      ballexit[i] = 1;
1164
      mutex_unlock (&delmutex);
1165
 
1166
      return (1);
1167
   }
1168
   return (0);
1169
}