Blame |
Last modification |
View Log
| RSS feed
/*--------------------------------------------------------------*/
/* BILIARDO: FILE CONTENENTE TASK PALLA E SCHEDULAZIONE */
/*--------------------------------------------------------------*/
#include <kernel/func.h>
#include <stdlib.h>
#include <math.h>
#include "biliardo.h"
#include "posizion.h"
#define R 4 // dimensioni della palla
#define RB 7 // dimensioni della buca
#define COD_FRECCIA 64
static int ballexit
[BALL_MAX_P
]; // controllo eliminazione task palla
static int npc
= 0; // numero dei task palla in gioco
struct posizione PosPalla
[BALL_MAX_P
]; // posizione delle palle in gioco
int FlagPartita
= 0;
int ch
= 0, curs
= 0;
int punteggio
[2]; // punteggio relativo al giocatore
int giocatore
= 0; // giocatore
int bForza
;
TASK palla
(int i
) {
float oxf
, oyf
; // posizione precedente della palla
int col
;
setPalla
(i
);
mutex_lock
(&palmutex
);
col
= PosPalla
[i
].
col;
oxf
= PosPalla
[i
].
x;
oyf
= BALL_Y
- PosPalla
[i
].
y;
mutex_unlock
(&palmutex
);
mutex_lock
(&mutex
);
grx_disc
(oxf
, oyf
, R
, col
);
grx_text
(" ",432,85, black
, black
);
mutex_unlock
(&mutex
);
while (1) {
mutex_lock
(&mutex
);
grx_disc
(oxf
, oyf
, R
, 0);
// grx_line(oxf, oyf, oxf+vx, oyf-vy, 0);
mutex_unlock
(&mutex
);
mutex_lock
(&palmutex
);
oxf
= PosPalla
[i
].
x;
oyf
= BALL_Y
- PosPalla
[i
].
y;
mutex_unlock
(&palmutex
);
mutex_lock
(&delmutex
);
if (ballexit
[i
]) {
npc
--;
mutex_unlock
(&delmutex
);
return 0;
}
mutex_unlock
(&delmutex
);
mutex_lock
(&mutex
);
grx_disc
(oxf
, oyf
, R
, col
);
// grx_line(oxf, oyf, oxf+vx, oyf-vy, col);
mutex_unlock
(&mutex
);
task_endcycle
();
}
}
TASK sched
() {
int i
, j
;
int k
;
char strTmp
[21];
struct posizione posIn
[BALL_MAX_P
];
struct posizione posOut
[BALL_MAX_P
];
struct posizione pos
[BALL_MAX_P
];
int flag
, bBevuta
= 0;
float dist
= 0;
float dx
, dy
; // variazione coordinate
float dt
; /* incremento temporale */
float modx
, mody
;
// angolo formato dalla retta passante per il baricentro delle palle in collisione
float thetaB1
= 0, thetaB2
= 0;
float tratto
; //tratto percorso
float thetaO1
, thetaO2
;
float attr
= 0.0021; // attrito applicato ad ogni palla
float acc
;
float g
= 9.86; // forza di gravit
utilizzata per il calcolo dell'attrito
float v0
= 0;
float xCurs
, yCurs
;
int bRiposiz
= 1;
int punteggio
[2];
int giocatore
= 0;
int sign
;
float v1x
, v1y
, v2x
, v2y
;
float phi
;
float thetaV1
, thetaV2
;
float thetaBarOld1
, thetaBarOld2
;
// evita che venga segnalata pi volte una collisione
int flag1coll
[BALL_MAX_P
];
// segna nella locazione di una palla con quale altra palla ha colliso
int flagCollCorr
[BALL_MAX_P
];
// ricorda per ogni palla quale stata la collisione precedente
int flagCollPrec
[BALL_MAX_P
];
int flagAgg
[BALL_MAX_P
];
int flagAggNum
[BALL_MAX_P
];
for (i
=0; i
<BALL_MAX_P
; i
++) {
flagCollPrec
[i
] = -1;
}
dt
= ((float)PERIOD_BALL
)/40000;
acc
= attr
* g
;
flag
= 1;
k
= 0;
while (1) {
if (ch
== 'i') {
punteggio
[0] = 0, punteggio
[1] = 0;
ch
= 0;
}
if (FlagPartita
) {
// inizio mutex
mutex_lock
(&palmutex
);
if (PosPalla
[i
].
theta < 0)
PosPalla
[i
].
theta += 2*PI
;
else
if (PosPalla
[i
].
theta > 2*PI
)
PosPalla
[i
].
theta -= 2*PI
;
for(i
=0; i
<BALL_MAX_P
; i
++) {
flag1coll
[i
] = 0;
flagCollCorr
[i
] = -1;
flagAgg
[i
] = 0;
posIn
[i
].
x = posOut
[i
].
x = PosPalla
[i
].
x;
posIn
[i
].
y = posOut
[i
].
y = PosPalla
[i
].
y;
posIn
[i
].
v = posOut
[i
].
v = PosPalla
[i
].
v;
posIn
[i
].
theta = posOut
[i
].
theta = PosPalla
[i
].
theta;
}
mutex_unlock
(&palmutex
);
// fine mutex
for(i
=0; i
<BALL_MAX_P
; i
++) {
for(j
=0; j
<BALL_MAX_P
; j
++) {
if (i
< j
&& flagCollCorr
[i
] == -1) {
if(posIn
[i
].
x-R
>= posIn
[j
].
x-R
&& posIn
[i
].
x-R
<= posIn
[j
].
x+R
&& posIn
[i
].
y-R
>= posIn
[j
].
y-R
&& posIn
[i
].
y-R
<= posIn
[j
].
y+R
) {
flagCollCorr
[i
] = j
;
flagCollCorr
[j
] = i
;
break;
}
else
if(posIn
[i
].
x-R
>= posIn
[j
].
x-R
&& posIn
[i
].
x-R
<= posIn
[j
].
x+R
&& posIn
[i
].
y+R
>= posIn
[j
].
y-R
&& posIn
[i
].
y+R
<= posIn
[j
].
y+R
) {
flagCollCorr
[i
] = j
;
flagCollCorr
[j
] = i
;
break;
}
else
if(posIn
[i
].
x+R
>= posIn
[j
].
x-R
&& posIn
[i
].
x+R
<= posIn
[j
].
x+R
&& posIn
[i
].
y+R
>= posIn
[j
].
y-R
&& posIn
[i
].
y+R
<= posIn
[j
].
y+R
) {
flagCollCorr
[i
] = j
;
flagCollCorr
[j
] = i
;
break;
}
else
if(posIn
[i
].
x+R
>= posIn
[j
].
x-R
&& posIn
[i
].
x+R
<= posIn
[j
].
x+R
&& posIn
[i
].
y-R
>= posIn
[j
].
y-R
&& posIn
[i
].
y-R
<= posIn
[j
].
y+R
) {
flagCollCorr
[i
] = j
;
flagCollCorr
[j
] = i
;
break;
}
else {
flagCollCorr
[i
] = -1;
flagCollPrec
[i
] = -1;
}
} // fine if(i!=j)
} // fine ciclo for(j)
if (flagCollCorr
[i
] != -1 && flagCollCorr
[i
] != flagCollPrec
[i
]) {
dist
= sqrt(pow(posIn
[i
].
x - posIn
[flagCollCorr
[i
]].
x,2)
+ pow(posIn
[i
].
y - posIn
[flagCollCorr
[i
]].
y,2));
if (dist
< 2*R
) {
flagAgg
[i
] = 1;
flagAgg
[flagCollCorr
[i
]] = 1;
dist
= ceil (2*R
-dist
);
if ((int)dist
%2 != 0)
dist
+= 1;
flagAggNum
[i
] = (int)dist
/2;
}
// permette la sola collisione di due palle contemporaneamente
flag1coll
[i
] = 1;
flagCollPrec
[i
] = flagCollCorr
[i
];
}
} // fine ciclo for(i)
for(i
=0; i
<BALL_MAX_P
; i
++) { // inizio ciclo for calcolo collisioni
if (flag1coll
[i
]) {
if (flag1coll
[0])
bBevuta
= 0;
sign
= 1;
modx
= posIn
[i
].
x - posIn
[flagCollCorr
[i
]].
x;
mody
= posIn
[i
].
y - posIn
[flagCollCorr
[i
]].
y;
if (modx
*mody
< 0) sign
= 0;
if (modx
< 0) modx
= -modx
;
if (mody
< 0) mody
= -mody
;
// prima palla
if (posIn
[i
].
x <= posIn
[flagCollCorr
[i
]].
x && posIn
[i
].
y <= posIn
[flagCollCorr
[i
]].
y) {
// angolo formato dalla retta passante per il baricentro delle due palle
thetaB1
= atan (mody
/ modx
);
if (flagAgg
[i
]) {
posOut
[i
].
x -=flagAggNum
[i
], posOut
[i
].
y -=flagAggNum
[i
];
flagAgg
[i
] = 0;
}
}
else
if (posIn
[i
].
x >= posIn
[flagCollCorr
[i
]].
x && posIn
[i
].
y <= posIn
[flagCollCorr
[i
]].
y) {
thetaB1
= PI
- atan (mody
/ modx
);
if (flagAgg
[i
]) {
posOut
[i
].
x +=flagAggNum
[i
], posOut
[i
].
y -=flagAggNum
[i
];
flagAgg
[i
] = 0;
}
}
else
if (posIn
[i
].
x >= posIn
[flagCollCorr
[i
]].
x && posIn
[i
].
y >= posIn
[flagCollCorr
[i
]].
y) {
thetaB1
= PI
+ atan (mody
/ modx
);
if (flagAgg
[i
]) {
posOut
[i
].
x +=flagAggNum
[i
], posOut
[i
].
y +=flagAggNum
[i
];
flagAgg
[i
] = 0;
}
}
else
if (posIn
[i
].
x <= posIn
[flagCollCorr
[i
]].
x && posIn
[i
].
y >= posIn
[flagCollCorr
[i
]].
y) {
thetaB1
= 2*PI
- atan (mody
/ modx
);
if (flagAgg
[i
]) {
posOut
[i
].
x -=flagAggNum
[i
], posOut
[i
].
y +=flagAggNum
[i
];
flagAgg
[i
] = 0;
}
}
if (thetaB1
< 0)
thetaB1
+= 2*PI
;
else
if (thetaB1
> 2*PI
)
thetaB1
-= 2*PI
;
// seconda palla
if (posIn
[i
].
x >= posIn
[flagCollCorr
[i
]].
x && posIn
[i
].
y >= posIn
[flagCollCorr
[i
]].
y) {
// angolo formato dalla retta passante per il baricentro delle due palle
thetaB2
= atan (mody
/ modx
);
}
else
if (posIn
[i
].
x <= posIn
[flagCollCorr
[i
]].
x && posIn
[i
].
y >= posIn
[flagCollCorr
[i
]].
y) {
thetaB2
= PI
- atan (mody
/ modx
);
}
else
if (posIn
[i
].
x <= posIn
[flagCollCorr
[i
]].
x && posIn
[i
].
y <= posIn
[flagCollCorr
[i
]].
y) {
thetaB2
= PI
+ atan (mody
/ modx
);
}
else
if (posIn
[i
].
x >= posIn
[flagCollCorr
[i
]].
x && posIn
[i
].
y <= posIn
[flagCollCorr
[i
]].
y) {
thetaB2
= 2*PI
- atan (mody
/ modx
);
}
if (thetaB2
< 0)
thetaB2
+= 2*PI
;
else
if (thetaB2
> 2*PI
)
thetaB2
-= 2*PI
;
// aggiorno gli angoli rispetto al nuovo sistema di riferimento della prima palla
// con 0 in thetaB1-PI/2
posOut
[i
].
theta = posIn
[i
].
theta + PI
/2 - thetaB1
;
if (posOut
[i
].
theta < 0)
posOut
[i
].
theta += 2*PI
;
else
if (posOut
[i
].
theta > 2*PI
)
posOut
[i
].
theta -= 2*PI
;
thetaO1
= posOut
[i
].
theta;
// stessa cosa per la seconda palla con 0 in thetaB2-PI/2
posOut
[flagCollCorr
[i
]].
theta = posIn
[flagCollCorr
[i
]].
theta + PI
/2 - thetaB2
;
if (posOut
[flagCollCorr
[i
]].
theta < 0)
posOut
[flagCollCorr
[i
]].
theta += 2*PI
;
else
if (posOut
[flagCollCorr
[i
]].
theta > 2*PI
)
posOut
[flagCollCorr
[i
]].
theta -= 2*PI
;
thetaO2
= posOut
[flagCollCorr
[i
]].
theta;
thetaBarOld1
= thetaB1
;
thetaBarOld2
= thetaB2
;
thetaB1
= PI
/2;
thetaB2
= PI
/2;
// Ho l'angolo formato dalle due palle => aggiorno gli angoli rispetto
// al nuovo sistema di riferimento
if (cos(posOut
[i
].
theta) <= 0)
thetaV1
= PI
- posOut
[i
].
theta;
else
thetaV1
= -posOut
[i
].
theta;
if (thetaV1
< 0)
thetaV1
= -thetaV1
;
if (cos(posOut
[flagCollCorr
[i
]].
theta) <= 0)
thetaV2
= PI
- posOut
[flagCollCorr
[i
]].
theta;
else
thetaV2
= -posOut
[flagCollCorr
[i
]].
theta;
if (thetaV2
< 0)
thetaV2
= -thetaV2
;
v1x
= posIn
[i
].
v * pow(cos(thetaV1
), 2);
v1y
= posIn
[i
].
v * pow(sin(thetaV1
), 2);
v2x
= posIn
[flagCollCorr
[i
]].
v * pow(cos(thetaV2
), 2);
v2y
= posIn
[flagCollCorr
[i
]].
v * pow(sin(thetaV2
), 2);
// aggiusto i segni secondo il sistema della prima palla
if (cos(posOut
[i
].
theta) < 0)
v1x
= -v1x
;
if (sin(posOut
[i
].
theta) < 0)
v1y
= -v1y
;
if (cos(posOut
[flagCollCorr
[i
]].
theta) > 0)
v2x
= -v2x
;
if (sin(posOut
[flagCollCorr
[i
]].
theta) > 0)
v2y
= -v2y
;
if (!v1y
&& v2y
> 0) {
v2y
= 0;
}
if (v1y
< 0 && v1y
< v2y
) {
v2y
= v1y
;
}
// nuovo modulo della velocit
della palla 1
posOut
[i
].
v = sqrt(pow(v1x
, 2) + pow(v2y
, 2));
if (v1x
) {
phi
= atan (v2y
/ v1x
);
if (phi
< 0)
phi
= -phi
;
}
else
phi
= PI
/2;
if (v1x
>= 0 && v2y
>= 0) {
// primo quadrante
phi
= phi
;
}
else
if (v1x
<= 0 && v2y
>= 0) {
// secondo quadrante
phi
= PI
/2 + (PI
/2-phi
);
}
else
if (v1x
<= 0 && v2y
<= 0)
// terzo quadrante
phi
= PI
+ phi
;
else
if (v1x
>= 0 && v2y
<= 0)
// quarto quadrante
phi
= 3*PI
/2 + (PI
/2-phi
);
posOut
[i
].
theta = phi
;
if (posOut
[i
].
theta > 2*PI
)
posOut
[i
].
theta = posOut
[i
].
theta - 2*PI
;
else
posOut
[i
].
theta = posOut
[i
].
theta;
// riporto tutto nel sistema di riferimento iniziale
posOut
[i
].
theta += -PI
/2 + thetaBarOld1
;
if (posOut
[i
].
theta < 0)
posOut
[i
].
theta += 2*PI
;
else
if (posOut
[i
].
theta > 2*PI
)
posOut
[i
].
theta -= 2*PI
;
posOut
[flagCollCorr
[i
]].
theta += (-PI
/2 + thetaBarOld2
);
if (posOut
[flagCollCorr
[i
]].
theta < 0)
posOut
[flagCollCorr
[i
]].
theta += 2*PI
;
else
if (posOut
[flagCollCorr
[i
]].
theta > 2*PI
)
posOut
[flagCollCorr
[i
]].
theta -= 2*PI
;
thetaB1
= thetaBarOld1
;
thetaB2
= thetaBarOld2
;
/* if (flag2 < 4) {
itoa (i, strTmp);
grx_text(strTmp,322,185+flag2*22, gray, black );
itoa (flagCollCorr[i], strTmp);
grx_text(strTmp,322,195+flag2*22, gray, black );
sprintf (strTmp, "%f", posIn[i].theta*360/(2*PI));
grx_text(strTmp,342,185+flag2*22, gray, black );
sprintf (strTmp, "%f", posIn[flagCollCorr[i]].theta*360/(2*PI));
grx_text(strTmp,342,195+flag2*22, gray, black );
sprintf (strTmp, "%f", posOut[i].theta*360/(2*PI));
grx_text(strTmp,432,185+flag2*22, gray, black );
sprintf (strTmp, "%f", posOut[flagCollCorr[i]].theta*360/(2*PI));
grx_text(strTmp,432,195+flag2*22, gray, black );
sprintf (strTmp, "%f", thetaB1*360/(2*PI));
grx_text(strTmp,522,185+flag2*22, gray, black );
sprintf (strTmp, "%f", thetaB2*360/(2*PI));
grx_text(strTmp,522,195+flag2*22, gray, black );
// -----------------------
sprintf (strTmp, "%f", posIn[i].v);
grx_text(strTmp,322,290+flag2*22, gray, black );
sprintf (strTmp, "%f", posIn[flagCollCorr[i]].v);
grx_text(strTmp,322,300+flag2*22, gray, black );
sprintf (strTmp, "%f", v1x);
grx_text(strTmp,412,290+flag2*22, gray, black );
sprintf (strTmp, "%f", v2x);
grx_text(strTmp,412,300+flag2*22, gray, black );
sprintf (strTmp, "%f", v1y);
grx_text(strTmp,502,290+flag2*22, gray, black );
sprintf (strTmp, "%f", v2y);
grx_text(strTmp,502,300+flag2*22, gray, black );
sprintf (strTmp, "%f", posOut[i].v);
grx_text(strTmp,582,290+flag2*22, gray, black );
sprintf (strTmp, "%f", posOut[flagCollCorr[i]].v);
grx_text(strTmp,582,300+flag2*22, gray, black );
// -----------------------
sprintf (strTmp, "%f", thetaV1*360/(2*PI));
grx_text(strTmp,322,390+flag2*22, gray, black );
sprintf (strTmp, "%f", thetaV2*360/(2*PI));
grx_text(strTmp,322,400+flag2*22, gray, black );
sprintf (strTmp, "%f", thetaO1*360/(2*PI));
grx_text(strTmp,402,390+flag2*22, gray, black );
sprintf (strTmp, "%f", thetaO2*360/(2*PI));
grx_text(strTmp,412,400+flag2*22, gray, black );
flag2++;
}
*/
} // fine if flag1coll
// questo if fa i conti del movimento di ogni pallina
if(posOut
[i
].
v > 0) {
posOut
[i
].
v -= acc
* dt
;
tratto
= posOut
[i
].
v * dt
-0.5*acc
*dt
*dt
;
dx
= (float) (tratto
* cos(posOut
[i
].
theta));
dy
= (float) (tratto
* sin(posOut
[i
].
theta));
posOut
[i
].
x += dx
;
posOut
[i
].
y += dy
;
if (posOut
[i
].
x > BALL_XMAX
) {
posOut
[i
].
x = BALL_XMAX
;
posOut
[i
].
theta = PI
- posOut
[i
].
theta;
}
if (posOut
[i
].
x < BALL_XMIN
) {
posOut
[i
].
x = BALL_XMIN
;
posOut
[i
].
theta = PI
- posOut
[i
].
theta;
}
if (posOut
[i
].
y > BALL_YMAX
) {
posOut
[i
].
y = BALL_YMAX
;
posOut
[i
].
theta = -posOut
[i
].
theta;
}
if (posOut
[i
].
y < 0) {
posOut
[i
].
y = 0;
posOut
[i
].
theta = -posOut
[i
].
theta;
}
}
pos
[i
].
x = posOut
[i
].
x;
pos
[i
].
y = posOut
[i
].
y;
pos
[i
].
v = posOut
[i
].
v;
pos
[i
].
theta = posOut
[i
].
theta;
} //fine ciclo for calcolo collisioni
if (!pos
[0].
v && !pos
[1].
v && !pos
[2].
v && !pos
[3].
v && !pos
[4].
v && !pos
[5].
v &&
!pos
[6].
v && !pos
[7].
v && !pos
[8].
v && !pos
[9].
v && !pos
[10].
v) {
for (i
=0; i
<BALL_MAX_P
; i
++) {
flagCollPrec
[i
] = -1;
}
}
if (bRiposiz
&& flag
) {
mutex_lock
(&mutex
);
grx_text
("Modo riposizionamento palla bianca",322,85, white
, black
);
mutex_unlock
(&mutex
);
flag
= 0;
}
// posizionamento palla 0
if (bRiposiz
&& curs
) {
if (curs
== 77 && pos
[0].
x+R
/2 <= BALL_XMAX
) pos
[0].
x += 3;
if (curs
== 75 && pos
[0].
x-R
>= BALL_XMIN
) pos
[0].
x -= 3;
curs
= 0;
}
// entra in modalit
calibrazione forza
if (ch
== ' ' && !bForza
&& (!pos
[0].
v && !pos
[1].
v && !pos
[2].
v
&& !pos
[3].
v && !pos
[4].
v && !pos
[5].
v && !pos
[6].
v &&
!pos
[7].
v && !pos
[8].
v && !pos
[9].
v && !pos
[10].
v)) {
bForza
= 1;
ch
= 0, v0
= 3.5;
xCurs
= pos
[0].
x, yCurs
= BALL_Y
-pos
[0].
y+10;
if (yCurs
>= BALL_Y
) yCurs
= BALL_Y
-pos
[0].
y;
mutex_lock
(&mutex
);
grx_text
("Modo riposizionamento palla bianca",322,85, black
, black
);
grx_text
("Modo calibrazione forza",322,85, white
, black
);
grx_text
("Forza: ",322,95, white
, black
);
sprintf (strTmp
, "%2f", v0
);
grx_text
(strTmp
,402,95, red
, black
);
grx_line
(xCurs
-2, yCurs
, xCurs
+2, yCurs
, red
);
grx_line
(xCurs
, yCurs
+2, xCurs
, yCurs
-2, red
);
mutex_unlock
(&mutex
);
bRiposiz
= 0;
}
// calibrazione forza
if (ch
== 'a' && bForza
) {
if (v0
< 7.5)
v0
+= 0.3;
if (v0
> 7.5)
v0
= 7.5;
ch
= 0;
mutex_lock
(&mutex
);
grx_text
(" ",402,95, black
, black
);
sprintf (strTmp
, "%2f", v0
);
grx_text
(strTmp
,402,95, red
, black
);
mutex_unlock
(&mutex
);
}
else
if (ch
== 'z' && bForza
) {
if (v0
> 0)
v0
-= 0.1;
if (v0
< 0)
v0
= 0;
ch
= 0;
mutex_lock
(&mutex
);
grx_text
(" ",402,95, black
, black
);
sprintf (strTmp
, "%2f", v0
);
grx_text
(strTmp
,402,95, red
, black
);
mutex_unlock
(&mutex
);
}
// aggiusta il mirino
if (bForza
&& curs
) {
mutex_lock
(&mutex
);
grx_line
(xCurs
-2, yCurs
, xCurs
+2, yCurs
, black
);
grx_line
(xCurs
, yCurs
+2, xCurs
, yCurs
-2, black
);
if (curs
== 72 && yCurs
>= BALL_Y
-BALL_YMAX
-1) yCurs
-= 2;
if (curs
== 80 && yCurs
<= BALL_Y
) yCurs
+= 2;
if (curs
== 77 && xCurs
<= BALL_XMAX
) xCurs
+= 2;
if (curs
== 75 && xCurs
>= BALL_XMIN
) xCurs
-= 2;
grx_line
(xCurs
-2, yCurs
, xCurs
+2, yCurs
, red
);
grx_line
(xCurs
, yCurs
+2, xCurs
, yCurs
-2, red
);
mutex_unlock
(&mutex
);
curs
= 0;
bRiposiz
= 0;
}
// bevuta
if (!pos
[0].
v && bBevuta
) {
pos
[0].
x = BALL_XMIN
+100;
pos
[0].
y = 50;
pos
[0].
v = 0;
pos
[0].
theta = 0;
bRiposiz
= 1;
flag
= 1;
if (giocatore
)
giocatore
= 0;
else
giocatore
= 1;
bBevuta
= 0;
mutex_lock
(&mutex
);
grx_text
("Modo riposizionamento palla bianca",322,85, white
, black
);
mutex_unlock
(&mutex
);
}
// scocca il colpo di stecca
if (bForza
&& ch
== ' ') {
// mutex_lock(&palmutex);
pos
[0].
v = v0
;
if (pos
[0].
x-xCurs
)
pos
[0].
theta = atan ((BALL_Y
-pos
[0].
y-yCurs
)/(pos
[0].
x-xCurs
));
else
pos
[0].
theta = PI
/2;
if (pos
[0].
theta <0)
pos
[0].
theta = -pos
[0].
theta;
if (xCurs
<= pos
[0].
x && yCurs
>= BALL_Y
-pos
[0].
y)
// primo quadrante
pos
[0].
theta = pos
[0].
theta;
else
if (xCurs
>= pos
[0].
x && yCurs
>= BALL_Y
-pos
[0].
y)
// secondo quadrante
pos
[0].
theta = PI
/2 + (PI
/2-pos
[0].
theta);
else
if (xCurs
>= pos
[0].
x && yCurs
<= BALL_Y
-pos
[0].
y)
// terzo quadrante
pos
[0].
theta = PI
+ pos
[0].
theta;
else
if (xCurs
<= pos
[0].
x && yCurs
<= BALL_Y
-pos
[0].
y)
// quarto quadrante
pos
[0].
theta = 3*PI
/2 + (PI
/2-pos
[0].
theta);
// mutex_unlock(&palmutex);
mutex_lock
(&mutex
);
grx_line
(xCurs
-2, yCurs
, xCurs
+2, yCurs
, black
);
grx_line
(xCurs
, yCurs
+2, xCurs
, yCurs
-2, black
);
grx_text
("Modo calibrazione forza",322,85, black
, black
);
grx_text
("Forza: ",322,95, black
, black
);
grx_text
(" ",402,95, black
, black
);
mutex_unlock
(&mutex
);
ch
= bForza
= 0;
v0
= 0;
bBevuta
= 1;
}
if (ch
== 'x') {
for (i
=0; i
<BALL_MAX_P
; i
++) {
flagCollPrec
[i
] = -1;
}
ch
= 0;
}
itoa (giocatore
, strTmp
);
mutex_lock
(&mutex
);
grx_text
(strTmp
,432,110, red
, black
);
itoa (punteggio
[giocatore
], strTmp
);
grx_text
(strTmp
,432,120, red
, black
);
mutex_unlock
(&mutex
);
// aggiornamento della posizione delle palle
mutex_lock
(&palmutex
);
for (i
=0; i
<BALL_MAX_P
; i
++) {
if (controlloBuche
(pos
[i
].
x, pos
[i
].
y, i
)) {
if (i
) {
pos
[i
].
x = -10;
pos
[i
].
y = 30;
pos
[i
].
v = 0;
pos
[i
].
theta = 0;
punteggio
[giocatore
]++;
// itoa (npc, strTmp);
// grx_text(strTmp,322,285, black, red );
if (punteggio
[giocatore
] >= 5) {
itoa (punteggio
[giocatore
], strTmp
);
if (punteggio
[giocatore
] > 5) {
mutex_lock
(&mutex
);
grx_text
(strTmp
,432,120, red
, black
);
grx_text
("Vittoria giocatore:",432,85, red
, black
);
itoa (giocatore
, strTmp
);
grx_text
(strTmp
,592,85, red
, black
);
mutex_unlock
(&mutex
);
killball
();
}
if (punteggio
[giocatore
] == 5 && npc
== 2) {
mutex_lock
(&mutex
);
grx_text
(strTmp
,432,120, red
, black
);
grx_text
("Pareggio",432,85, red
, black
);
mutex_unlock
(&mutex
);
killball
();
}
}
}
else {
pos
[i
].
x = BALL_XMIN
+100;
pos
[i
].
y = 50;
pos
[i
].
v = 0;
pos
[i
].
theta = 0;
mutex_lock
(&delmutex
);
ballexit
[i
] = 0;
mutex_unlock
(&delmutex
);
bRiposiz
= 1;
flag
= 1;
if (giocatore
)
giocatore
= 0;
else
giocatore
= 1;
bBevuta
= 0;
}
}
PosPalla
[i
].
x = pos
[i
].
x;
PosPalla
[i
].
y = pos
[i
].
y;
if (pos
[i
].
v >= 0) {
PosPalla
[i
].
v = pos
[i
].
v;
if (pos
[i
].
theta > 2*PI
)
PosPalla
[i
].
theta = pos
[i
].
theta - 2*PI
;
else
if (pos
[i
].
theta < 0 )
PosPalla
[i
].
theta = pos
[i
].
theta + 2*PI
;
else
PosPalla
[i
].
theta = pos
[i
].
theta;
}
else {
PosPalla
[i
].
v = 0;
PosPalla
[i
].
theta = 0;
}
}
mutex_unlock
(&palmutex
);
}
else {
bRiposiz
= 1, flag
= 1;
bBevuta
= 0;
}
task_endcycle
();
} // fine ciclo while esterno
}
void inizioPartita
() {
if (!FlagPartita
) {
hardball
();
giocatore
= 0;
punteggio
[0] = 0;
punteggio
[1] = 0;
FlagPartita
= 1;
}
}
void killball
() {
int i
;
bForza
= 0;
mutex_lock
(&delmutex
);
for (i
=0; i
<BALL_MAX_P
; i
++)
ballexit
[i
] = 1;
mutex_unlock
(&delmutex
);
FlagPartita
= 0;
}
void assegnaForza
(KEY_EVT
*k
) {
ch
= k
->ascii
;
}
void movCursore
(KEY_EVT
*k
) {
curs
= k
->ascii
;
}
/*
void ballfun(KEY_EVT *k)
{
SOFT_TASK_MODEL mp;
int r,g,b;
PID pid;
char palla_str[]="palla ";
soft_task_default_model(mp);
soft_task_def_level(mp,1);
soft_task_def_ctrl_jet(mp);
soft_task_def_arg(mp);
soft_task_def_group(mp, BALL_GROUP);
soft_task_def_met(mp, WCET_BALL);
soft_task_def_period(mp,PERIOD_BALL);
soft_task_def_usemath(mp);
pid = task_create(palla_str, palla, &mp, NULL);
if (pid != NIL) {
task_activate(pid);
}
}
*/
// avvio dei task palla
void hardball
()
{
HARD_TASK_MODEL mp
;
PID pid
;
char pallaStr
[]="palla ";
int i
;
if (npc
== BALL_MAX_P
) return;
for(i
=0;i
<BALL_MAX_P
;i
++) {
ballexit
[i
] = 0;
itoa(i
,pallaStr
+6);
hard_task_default_model
(mp
);
hard_task_def_ctrl_jet
(mp
);
hard_task_def_arg
(mp
, (void *)i
);
hard_task_def_wcet
(mp
, WCET_BALL
);
hard_task_def_mit
(mp
,PERIOD_BALL
);
hard_task_def_group
(mp
, BALL_GROUP
);
hard_task_def_usemath
(mp
);
pid
= task_create
(pallaStr
, palla
, &mp
, NULL
);
if (pid
== NIL
) {
grx_close
();
perror("Could not create task <pallaEDF>");
sys_end
();
}
else {
npc
++;
}
}
group_activate
(BALL_GROUP
);
}
// avvio del task di contollo
void hardSched
()
{
HARD_TASK_MODEL mp
;
PID pid
;
hard_task_default_model
(mp
);
hard_task_def_ctrl_jet
(mp
);
// hard_task_def_arg(mp, (void *)1);
hard_task_def_wcet
(mp
, WCET_SCHED
);
hard_task_def_mit
(mp
, PERIOD_SCHED
);
hard_task_def_usemath
(mp
);
pid
= task_create
("Schedular", sched
, &mp
, NULL
);
if (pid
== NIL
) {
grx_close
();
perror("Could not create task <Schedulatore>");
sys_end
();
}
else
task_activate
(pid
);
}
/*--------------------------------------------------------------*/
/* MAIN process */
/*--------------------------------------------------------------*/
void scenario_ball
()
{
int i
;
// Margine dello schermo
grx_rect
(0, 0, 639, 479, red
);
grx_line
(320,78,639,78,red
);
grx_line
(320,0,320,479,red
);
// Tavolo da biliardo
grx_rect
(60,30,260,430,lime
);
for (i
=1; i
<27; i
++) {
grx_rect
(60-i
,30-i
,260+i
,430+i
,brown
);
}
// buche del tavolo
grx_disc
(62, 32, RB
, black
);
grx_disc
(258, 32, RB
, black
);
grx_disc
(62, 230, RB
, black
);
grx_disc
(258, 230, RB
, black
);
grx_disc
(62, 428, RB
, black
);
grx_disc
(258, 428, RB
, black
);
grx_line
(320,105,639,105,red
);
grx_line
(320,130,639,130,red
);
grx_text
("Giocatore:" ,322,110, red
, black
);
grx_text
("Punteggio:" ,322,120, red
, black
);
}
void init_ball
(void)
{
KEY_EVT k
;
k.
flag = 0;
k.
scan = KEY_I
;
k.
ascii = 'i';
keyb_hook
(k
,assegnaForza
);
keyb_hook
(k
,inizioPartita
);
/* intercetta il tasto 'spazio' per passare in modo posizionamento
e modo forza, mi serve per dare un colpo di stecca */
k.
flag = 0;
k.
scan = KEY_SPC
;
k.
ascii = ' ';
keyb_hook
(k
,assegnaForza
);
// inizia una nuova partita
k.
flag = 0;
k.
scan = KEY_BKS
;
k.
ascii = ' ';
keyb_hook
(k
,killball
);
k.
flag = 0;
k.
scan = KEY_X
;
k.
ascii = 'x';
keyb_hook
(k
,assegnaForza
);
k.
flag = 0;
k.
scan = KEY_A
;
k.
ascii = 'a';
keyb_hook
(k
,assegnaForza
);
k.
flag = 0;
k.
scan = KEY_Z
;
k.
ascii = 'z';
keyb_hook
(k
,assegnaForza
);
k.
flag = COD_FRECCIA
;
k.
scan = 72;
k.
ascii = 72;
keyb_hook
(k
,movCursore
);
k.
flag = COD_FRECCIA
;
k.
scan = 75;
k.
ascii = 75;
keyb_hook
(k
,movCursore
);
k.
flag = COD_FRECCIA
;
k.
scan = 77;
k.
ascii = 77;
keyb_hook
(k
,movCursore
);
k.
flag = COD_FRECCIA
;
k.
scan = 80;
k.
ascii = 80;
keyb_hook
(k
,movCursore
);
}
// inizializzzazione task di schedulazione
void initSched
(void) {
hardSched
();
}
// inizializzazione delle posizioni delle palle
void setPalla
(int num
) {
int nPalla
= num
;
nPalla
++;
switch(nPalla
) {
case 1:
PosPalla
[nPalla
-1].
x = BALL_XMIN
+ 100;
PosPalla
[nPalla
-1].
y = 50;
PosPalla
[nPalla
-1].
v = 0;
PosPalla
[nPalla
-1].
theta = 0;
PosPalla
[nPalla
-1].
col = white
;
break;
case 2:
PosPalla
[nPalla
-1].
x = BALL_XMIN
+ 100;
PosPalla
[nPalla
-1].
y = 300;
PosPalla
[nPalla
-1].
v = 0;
PosPalla
[nPalla
-1].
theta = 0;
PosPalla
[nPalla
-1].
col = green
;
break;
case 3:
PosPalla
[nPalla
-1].
x = BALL_XMIN
+ 90;
PosPalla
[nPalla
-1].
y = 310;
PosPalla
[nPalla
-1].
v = 0;
PosPalla
[nPalla
-1].
theta = 0;
PosPalla
[nPalla
-1].
col = green
;
break;
case 4:
PosPalla
[nPalla
-1].
x = BALL_XMIN
+ 110;
PosPalla
[nPalla
-1].
y = 310;
PosPalla
[nPalla
-1].
v = 0;
PosPalla
[nPalla
-1].
theta = 0;
PosPalla
[nPalla
-1].
col = green
;
break;
case 5:
PosPalla
[nPalla
-1].
x = BALL_XMIN
+ 80;
PosPalla
[nPalla
-1].
y = 320;
PosPalla
[nPalla
-1].
v = 0;
PosPalla
[nPalla
-1].
theta = 0;
PosPalla
[nPalla
-1].
col = green
;
break;
case 6:
PosPalla
[nPalla
-1].
x = BALL_XMIN
+ 100;
PosPalla
[nPalla
-1].
y = 320;
PosPalla
[nPalla
-1].
v = 0;
PosPalla
[nPalla
-1].
theta = 0;
PosPalla
[nPalla
-1].
col = green
;
break;
case 7:
PosPalla
[nPalla
-1].
x = BALL_XMIN
+ 120;
PosPalla
[nPalla
-1].
y = 320;
PosPalla
[nPalla
-1].
v = 0;
PosPalla
[nPalla
-1].
theta = 0;
PosPalla
[nPalla
-1].
col = green
;
break;
case 8:
PosPalla
[nPalla
-1].
x = BALL_XMIN
+ 70;
PosPalla
[nPalla
-1].
y = 330;
PosPalla
[nPalla
-1].
v = 0;
PosPalla
[nPalla
-1].
theta = 0;
PosPalla
[nPalla
-1].
col = green
;
break;
case 9:
PosPalla
[nPalla
-1].
x = BALL_XMIN
+ 90;
PosPalla
[nPalla
-1].
y = 330;
PosPalla
[nPalla
-1].
v = 0;
PosPalla
[nPalla
-1].
theta = 0;
PosPalla
[nPalla
-1].
col = green
;
break;
case 10:
PosPalla
[nPalla
-1].
x = BALL_XMIN
+ 110;
PosPalla
[nPalla
-1].
y = 330;
PosPalla
[nPalla
-1].
v = 0;
PosPalla
[nPalla
-1].
theta = 0;
PosPalla
[nPalla
-1].
col = green
;
break;
case 11:
PosPalla
[nPalla
-1].
x = BALL_XMIN
+ 130;
PosPalla
[nPalla
-1].
y = 330;
PosPalla
[nPalla
-1].
v = 0;
PosPalla
[nPalla
-1].
theta = 0;
PosPalla
[nPalla
-1].
col = green
;
break;
default:
PosPalla
[nPalla
-1].
x = BALL_XMIN
;
PosPalla
[nPalla
-1].
y = 0;
PosPalla
[nPalla
-1].
v = 0;
PosPalla
[nPalla
-1].
theta = 0;
PosPalla
[nPalla
-1].
col = green
;
break;
}
}
// controllo quando una palla finisce in buca
int controlloBuche
(float x
, float yRel
, int i
) {
float y
;
y
= BALL_Y
- yRel
;
if ((x
<= 62+RB
&& y
<= 32+RB
) || (x
>= 258-RB
&& y
<= 32+RB
) ||
(x
<= 62+RB
&& (y
>= 230-RB
&& y
<= 230+RB
)) || (x
>= 258-RB
&& (y
>= 230-RB
&& y
<= 230+RB
)) ||
(x
<= 62+RB
&& y
>= 428-RB
) || (x
>= 258-RB
&& y
>= 428-RB
)){
// palla in buca
mutex_lock
(&delmutex
);
ballexit
[i
] = 1;
mutex_unlock
(&delmutex
);
return (1);
}
return (0);
}