|
 |
-- Le
site -- |
 |
|
 |
-- Mes
projets sur TI -- |
 |
|
 |
--
Rubriques -- |
 |
|
|
|
|
Guide
de programmation pour PolySnd 2.0 en ASM et en C.
Animation
d'une balle avec du son (partie n°1):
Dans
ce programme nous allons vraiment commencer à exploiter
les performances de PolySnd v2.0, nous allons réaliser
un programme réalisant le déplacement d'une
balle avec un angle de 45°, chaque rebond sur l'écran
correspondera à un son.
Créez
un nouveau projet en C avec la librairie PolySnd v2.0
que vous nommerez 'example3'
avec le code de base pour initialiser PolySnd v2.0.
Nous
allons tout d'abord réaliser le programme sans
s'occuper du son, nous devons tout d'abord définir
le sprite et les déplacements de la balle, après
avoir fait ceci, nous réaliseront les effets sonores
et nous appliquerons à chaque collisions un son
différent.
Réalisation
du sprite (image) de la balle:
unsigned char ball_sprite [] = {0b00111100,
0b01111110,
0b11111111,
0b11111111,
0b11111111,
0b11111111,
0b01111110,
0b00111100};
|
Inserez ce code en
dessous de:
DEFINE_INT_HANDLER (myint2)
{
pokeIO (0x60001B,0);
}
|
Notre sprite fait
du 8x8 pixels, nous allons nous attquer au code de gestion
de la balle.
Réalisation
du code de déplacement de la balle:
La position
de notre balle sera définis par 2 variables xpos
et ypos
qui indiquerons ça positions en X et Y, à
chaque passage de boucle, nous incrémenterons ses
variables avec un facteur indiquant la direction de la
balle, soit xdir
pour son déplacement suivant X et ydir
suivant Y. Pour afficher et effacer correctement la balle,
nous l'afficherons avec un OU logique à la fin
de la boucle et nous l'effacerons avec OU exclusif (XOR)
au début de la boucle, bien sûr nous prenderons
soin d'afficher la balle avec une bonne vitesse et avec
une boucle d'attente.
Voici le code
du programme:
//
C Source File
// Created 11/10/2003; 17:13:50
#include
<tigcclib.h>
#include "polysnd2.h"
INT_HANDLER OldInt1 =
NULL;
INT_HANDLER OldInt2 =
NULL;
DEFINE_INT_HANDLER (myint2)
{
pokeIO (0x60001B,0);
}
unsigned char ball_sprite [] = {0b00111100,
0b01111110,
0b11111111,
0b11111111,
0b11111111,
0b11111111,
0b01111110,
0b00111100};
//Programme
principal
void
_main(void)
{
int
i;
short
xpos
= (LCD_WIDTH-1)/2;
short
ypos =
(LCD_HEIGHT-1)/2;
char
xdir =
1,
ydir =
1;
OldInt1
= GetIntVec (AUTO_INT_1);
OldInt2 = GetIntVec (AUTO_INT_2);
SetIntVec (AUTO_INT_1,
DUMMY_HANDLER);
SetIntVec (AUTO_INT_2,
myint2);
pSnd_EnableSound ();
pSnd_InstallSound ();
ClrScr
();
Sprite8 (xpos,
ypos,8
,ball_sprite, LCD_MEM, SPRT_OR);
while
(_keytest
(RR_ESC)==FALSE)
{
Sprite8 (xpos,
ypos,
8, ball_sprite, LCD_MEM, SPRT_XOR);
xpos+=xdir;
ypos+=ydir;
if (xpos+8
> (LCD_WIDTH-1))
xdir =
-1;
if (xpos
<
0)
xdir =1;
if (ypos+8
>
(LCD_HEIGHT-1))
ydir =
-1;
if (ypos
<
0)
ydir =
1;
Sprite8 (xpos,
ypos, 8,
ball_sprite, LCD_MEM, SPRT_OR);
for (i=0;
i<10000;
i++);
}
pSnd_UninstallSound ();
pSnd_DisableSound ();
SetIntVec (AUTO_INT_1,
OldInt1);
SetIntVec (AUTO_INT_2,
OldInt2);
}
|
Nous
allons nous occuper maintenant des divers parties de ce
code pour mieux comprendre ce programme et ainsi pouvoir
y introduire des séquences sonores sans trop de
difficultés.
int
i;
short
xpos
= (LCD_WIDTH-1)/2;
short
ypos =
(LCD_HEIGHT-1)/2;
char
xdir =
1,
ydir =
1;
|
Ici nous définissons
les variables qu'utilisera le programme:
i est
va permettre juste d'être utilisé dans la
boucle de temporisation.
xpos
et ypos sont les variables qui vont permettre
de situer la balle sur l'écran de telle sorte que
ça coordonné soit (xpos,ypos), ici nous
les inialisons de tel sorte qu'au lancement du programme
la balle ce situe au centre de l'écran et ce sur
n'importe quel modèle de calculatrice.
xdir
et ydir permettent de définir le
sens de déplacement de la balle, dans notre programme,
ses variables ne pourrons prendre que 2 valeurs (-1 ou
1), si xdir=1, la balle ce déplacera vers la droite
et si xdir=-1, vers la gauche, s'est le même principe
pour ydir. Si ydir=-1, la balle ce déplacera vers
le haut et si ydir=1, vers le bas.
Voilà
nos variables, maintenant nous devons les exploiter:
ClrScr ();
Sprite8 (xpos,
ypos,8
,ball_sprite, LCD_MEM, SPRT_OR);
while
(_keytest
(RR_ESC)==FALSE)
{
Sprite8 (xpos,
ypos,
8, ball_sprite, LCD_MEM, SPRT_XOR);
xpos+=xdir;
ypos+=ydir;
if (xpos+8
> (LCD_WIDTH-1))
xdir =
-1;
if (xpos
<
0)
xdir =1;
if (ypos+8
>
(LCD_HEIGHT-1))
ydir =
-1;
if (ypos
<
0)
ydir =
1;
Sprite8 (xpos,
ypos, 8,
ball_sprite, LCD_MEM, SPRT_OR);
for (i=0;
i<10000;
i++);
}
|
Nous
effacons tout d'abord l'écran avec ClrScr
(à savoir que c'est une fonction de TIGCC) et nous
affichons la balle avec sprite8 en mode
OU logique.
La boucle
while execute une série d'instruction
entre {} tant que
la condition est vrai, ici tant que nous n'avons pas appuyez
sur la touche ESC. Après nous nous occupons d'effacer
la balle sur l'écran en l'affichant avec sprite8
mais en mode OU exclusif (XOR), nous ajoutant xdir
à xpos et ydir à
ypos de telle sorte d'effectuer le mouvement
de la balle. Une fois cette étape d'effectué,
il faut vérifier que la balle ne sorte pas de l'écran,
pous cela on applique des collisions entre les points
ce situant à l'extremité de la balle donc
si nous voulons tester correctement si il y a collisions
avec le bas de l'écran et la balle nous devons
ajouter 8 à xpos dans notre
condition car la balle fait 8 pixels de hauteur et procéder
de la même façon pour les autres collisions,
mais au lieu de changer xpos ou ypos
dans notre résultat , nous changerons les
vecteurs de directions xdir ou ydir.
Et ensuite pour finir nous affichons la balle avec sprite8
en mode OU logique et nous effectuons une boucle
de temporisation avec for pour que la
balle ne soit pas trop rapide et que son temps d'affichage
soit visible.
Nous allons donc
maintenant créer les 4 séquences audio de
collisions avec l'écran, pour cela vous devez créer
un nouveau fichier du type header (portant l'extension
h) que vous nommerez 'sounds_ball.h'
et l'inclure dans le projet en tapant au début
du code '#include
"sounds_ball.h"'. Ouvrez le fichier
'sounds_ball.h'
et copiez le code suivant:
//C Source File //Created 11/10/2003; 17:13:50
//Collision avec la gauche
unsigned short collide_left[]={2500,15,
1415,21,
1000,30,
2000,10,
0xFFFF};
//Collision avec la droite
unsigned short collide_right[]={5500,15,
2415,21,
3000,30,
4000,10,
0xFFFF};
//Collision vers le haut
unsigned short collide_up[]={1250,10,
2300,30,
3800,10,
4500,10,
0xFFFF};
//Collision vers le bas
unsigned short collide_down[]={5845,5,
600,10,
5423,30,
8645,20,
0xFFFF};
|
Voici
enfin notre fichier 'sounds_ball.h'
remplit de données sonores, ici nous avons réaliser
4 listes de données pour PlayFX, les données
de PlayFX s'ordonnent de façon précise:
fréquence,
durée,
fréquence,
durée
.... fréquence,
durée,
0xFFFF
La fréquence
peut aller de 0 (considéré comme une pause)
à 32768 Hz, ses valeurs ne sont pas précise
et les durées vont de 1 à 255 et sont en
cycles tempo, soit 32 correspondant à une noire.
Ce mode est très difficile à utiliser mais
produit des résultats assez impressionnant. (note:
c'est le seul mode qui n'a pas de logiciel de conversion).
Une liste de données pour PlayFX doit toujhours
ce terminer par 0xFFFF
et ce pour indiquer ça fin à PolySnd v2.0.
Voici maintenant
le code du programme principal, nous avons juste modifié
les conditions lors de collisions:
//
C Source File
// Created 11/10/2003; 17:13:50
#include
<tigcclib.h>
#include "polysnd2.h"
INT_HANDLER OldInt1 =
NULL;
INT_HANDLER OldInt2 =
NULL;
DEFINE_INT_HANDLER (myint2)
{
pokeIO (0x60001B,0);
}
unsigned char ball_sprite [] = {0b00111100,
0b01111110,
0b11111111,
0b11111111,
0b11111111,
0b11111111,
0b01111110,
0b00111100};
//Programme
principal
void
_main(void)
{
int
i;
short
xpos
= (LCD_WIDTH-1)/2;
short
ypos =
(LCD_HEIGHT-1)/2;
char
xdir =
1,
ydir =
1;
OldInt1
= GetIntVec (AUTO_INT_1);
OldInt2 = GetIntVec (AUTO_INT_2);
SetIntVec (AUTO_INT_1,
DUMMY_HANDLER);
SetIntVec (AUTO_INT_2,
myint2);
pSnd_EnableSound ();
pSnd_InstallSound ();
pSnd_PlayMode
(MONO);
pSnd_SetTempo (1000);
ClrScr
();
Sprite8 (xpos,
ypos,8
,ball_sprite, LCD_MEM, SPRT_OR);
while
(_keytest
(RR_ESC)==FALSE)
{
Sprite8 (xpos,
ypos,
8, ball_sprite, LCD_MEM, SPRT_XOR);
xpos+=xdir;
ypos+=ydir;
if (xpos+8>(LCD_WIDTH-1))
{
xdir=-1;
pSnd_PlayFX_voice1
(collide_right);
pSnd_SetState
(VOICE1);
}
if (xpos<0)
{
xdir=1;
pSnd_PlayFX_voice1
(collide_left);
pSnd_SetState
(VOICE1);
}
if (ypos+8>(LCD_HEIGHT-1))
{
ydir=-1;
pSnd_PlayFX_voice1
(collide_down);
pSnd_SetState
(VOICE1);
}
if (ypos<0)
{
ydir=1;
pSnd_PlayFX_voice1
(collide_up);
pSnd_SetState
(VOICE1);
}
Sprite8 (xpos,
ypos, 8,
ball_sprite, LCD_MEM, SPRT_OR);
for (i=0;
i<10000;
i++);
}
pSnd_UninstallSound ();
pSnd_DisableSound ();
SetIntVec (AUTO_INT_1,
OldInt1);
SetIntVec (AUTO_INT_2,
OldInt2);
}
|
Nous
réglons PolySnd v2.0 en mode mono grâce à
pSnd_PlayMode puis nous paramètrons
le tempo à 1000 bpm avec SetTempo,
ici pSnd_SetTempo_voice1 aurait suffit.
Dans
chaque conditions de collisions nous jouant un son ce
trouvant dans le fichier 'sounds_ball.h'
avec pSnd_PlayFX_voice1 et nous donnons
l'ordre à PolySnd v2.0 de jouer le mode de la voie1
avec pSnd_SetState (VOICE1), ici comme nous
sommes en mono, VOICE1 suffit. PolySnd v2.0 n'attend
pas qu'un mode soit finit de jouer pour executer le suivant,
celui qui était en cours et ignoré au profit
du nouveau mode et des nouvelles données (bien
sûr il est toujours possible de programmer une gestion
de modes...).
Télécharger
example3.zip partie 1.
Animation
d'une balle avec du son (partie n°2):
Nous
allons réaliser le même programme que précédément
mais cette fois si en donnant la priorité au son
et donc bloquant le cours du programme lorsqu'un son est
joué. Vous allez constater que la balle subira
des ralentissements. Mais cette méthode est utile
dans le cas ou vous devez executer des actions en fonction
du son.
Nous
allons donc executer une boucle qui devra attendre la
fin du mode en cours, pour cela insérez cette ligne
de code en dessous pSnd_SetState_voice1 (VOICE1);.
while
(pSnd_GetState
()==VOICE1);
|
La boucle
while s'executera tant que le mode en cours
n'est pas finit, donc tant que pSnd_GetState
est égale à VOICE1.
Télécharger
example3.zip partie 2.
Rubrique
suivante.
|
|
|