Page 6 sur 7
Publié : jeu. sept. 22, 2011 3:02 am
par ivanwfr
Je vais prendre le temps de creuser la question mais j'ai déjà 3 remarques:
1 - pour initialiser une variable au démarrage, il suffit de la déclarer en dehors de la fonction main() et plus généralement de toute fonction, après les includes par exemple.
int flagHover = 1;
2 - Si tu cherches à trouver plus simple que de passer par des fonctions, ça n'est manifestement pas en partant comme
A mon avis, le plus simple passe toujours par une construction modulaire. Et les fonctions ne sont pas autre chose que des module dans lesquels on ne fait qu'une seule chose à la fois, histoire de rendre tout ça aussi lisible que possible, sans tout un tas de virgules, de parenthèses et de guillemets.
3 - Il se pourrait bien que les instructions dans les blocs EXEC() soient évalués à chaque exécussion, mieux vaut une fonction qui sera digérée une fois pour toute par le compilateur au lancement du script et transformée en binaire pour être éxécutée quelques milliers de fois plus facilement par le processeur.
C'est tout ça une fonction !
Je vais jouer avec ça pour voir ce que ça peut donner...
Publié : jeu. sept. 22, 2011 2:33 pm
par ivanwfr
Voilà où j'en suis arrivé en cherchant à faire au plus simple / lisible / efficace.
Code : Tout sélectionner
include "target.tmh"
int main() {
if(Init(&EveantHandle)) return 1;
// LED FLASHING module key binding
MapKey(&Throttle, LTB, EXEC("flashLED();"));
}
int EventHandle(int type, alias o, int x) { DefaultMapping(&o, x); }
// LED FLASHING MODULE
// ...these are literal code replacement wordings (to make it more readeable)
define FLASHING_DEV &Throttle
define FLASHING_LED OUT_ID_LED_5
define FLASHING_INTERVAL_MS 250
// ...needs tuning according to involved MFDs LEDs
// ...this is a GLOBAL VARIABLE (shared by any funcion)
int flagHover = 0;
// ...this is what gets EXECuted when some button is pressed
int flashLED()
{
flagHover = (flagHover == 0); // toggle 1, 0, 1, 0, ...
if(flagHover == 1) flashingLED(0);
}
// ...this is a FUNCTION THAT REPEATEDLY CALLS ITSELF after some delay
// ...as long as flagHover variable is not cleared by another call to flashLED()
int flashingLED(int dummy) // ...this dummy argument is not used here
{
if(flagHover > 0) {
GameOutput(&Throttle, FLASHING_LED, 2); // TOGGLE LED
DeferCall(FLASHING_INTERVAL_MS, &flashingLED, 0); // ...go on flashing
} else {
GameOutput(&Throttle, FLASHING_LED, 0); // STOP (LED turned off)
}
}
MERCI bcp "MAITRE" !
Publié : jeu. sept. 22, 2011 10:07 pm
par hellfrog
1 - pour initialiser une variable au démarrage, il suffit de la déclarer en dehors de la fonction main() et plus généralement de toute fonction, après les includes par exemple.
int flagHover = 1;
en voilà une nouvelle !
ça va me simplifier la vie ça !
question :
le fait d'avoir une fonction qui s'appelle elle-même indéfiniment ne cause pas une saturation mémoire ? (il n'y a pas d'arrêt du DeferCall comme on peut en avoir avec les REXEC ?)
si j'ai bien compris tu rappelles la fonction
flashingLED() dans cette ligne
Code : Tout sélectionner
DeferCall(FLASHING_INTERVAL_MS, [color=Yellow]&flashingLED[/color], 0);
avec le "
&" devant
flashingLED ?
quelle est la différence avec
Code : Tout sélectionner
DeferCall(FLASHING_INTERVAL_MS, [color=Yellow]EXEC("flashingLED();")[/color], 0);
Publié : ven. sept. 23, 2011 4:00 am
par ivanwfr
Cet usage de la fonction DeferCall() consiste effectivement à faire appeler la fonction flashingLED() par elle-même mais comme ça résulte en une séquence d'appels, avec un délai (1/4 de seconde dans ce cas), ça ne risque pas de s'empiler de manière incontrôlée. Ca ne fait que 4 appels par seconde ... Occupation CPU = 0 dans le TaskManager.
Pour ce qui est de REXEC(), il s'agit d' une macro interne à TARGET qui utilise également DeferCall() en boucle ... qu'il s'agit bien d'arrêter un jour ou l'autre
DeferCall() est un timer à 1 coup qui appelle une fonction lorsque le temps spécifié est écoulé.
Le
& devant flashingLED() veut dire "adresse de" variable (ou de fonction), c.a.d. une case mémoire dans laquelle il y a soit une valeur a utiliser
(variable) ou du code à exécuter
(fonction) ... C'est un héritage du language C qui permet de passer l'adresse d'une fonction à une fonction ... tout est permis ... dans la mesure où on comprend ce qu'on fait ... et ça peut occuper quelques dizaines d'années sans en trouver les limites
Quant à DeferCall(FLASHING_INTERVAL_MS,
EXEC("flashingLED();"), 0); la seule chose à retenir c'est que ça ne
doit pas marcher et que si ça fait quand même quelque chose sans générer d'erreur et bien ce serait une grosse
connerie de la part de TM...
- EXEC() est un macro-commande, ce qui veut dire qu'une prédigestion de l'interpréteur du script doit remplacer EXEC(...) par du "vrai code".
- DeferCall() ne peut supporter que l'adresse mémoire d'une fonction comme deuxième argument.
1 + 2 = ERREUR ... CQFD
D'une manière plus générale, je dirais que ces macros internes (mots tout en majuscules) ne doivent apparaitre que dans les instructions du genre MapKey() qui sont prêtes à les traiter... C'est l'interpréteur qui va récupérer le code équivalent et - peut-être - le compiler pour en faire une fonction dont il mettra l'
&adresse à la place. Mieux vaut en limiter l'usage et les réserver aux seuls cas illustrés dans le manuel.
Publié : ven. sept. 23, 2011 9:34 pm
par hellfrog
j'avais pondu ça : moins efficace et qui marche pas... sans doute à cause d'un pb de & sr les variables...
Code : Tout sélectionner
int flag_hover = 0;
int func_hover(alias flag_Hover) // {{{ function to press hover autopilot and to flash led on mfd if on
{
if(&flag_Hover == 0)
{
REXEC(39, 250, "
LMFD_LED2_Max();
Sleep(100);
LMFD_LED2_Min()
Sleep(100);
");
}
else
{
if(&flag_Hover ==1)
{
StopAutoRepeat(39);
LMFD_LED2_Min();
}
else
// should not occur : no ActKey
Break;
}
EXEC("ActKey(PULSE+KEYON+Hover_On_Off);");
&flag_Hover = !&&flag_hover;
}
int LMFD_LED2_Max() {GameOutput( &LMFD, OUT_ID_LED_INTENSITY, 200); GameOutput( &LMFD, OUT_ID_LED_2 , 1);}
int LMFD_LED2_Min() {GameOutput( &LMFD, OUT_ID_LED_2 , 0); GameOutput( &LMFD, OUT_ID_LED_INTENSITY, 20); }
// }}}
après fusion avec ton code
ça donne ça :
Code : Tout sélectionner
int main()
{
MapKey(&Throttle, LTB, EXEC("ActKey(PULSE+KEYON+Hover_On_Off);flashLED_Hover()");
}
int EventHandle(int type, alias o, int x)
{
DefaultMapping(&o, x);
}
// {{{
int flagHover = 0;
// ...this is what gets EXECuted when some button is pressed
int flashLED_Hover()
{
flagHover = (flagHover == 0); // toggle 1, 0, 1, 0, ...
if(flagHover == 1) flashLED_Hover_sub1(0);
}
// ...this is a FUNCTION THAT REPEATEDLY CALLS ITSELF after some delay
// ...as long as flagHover variable is not cleared by another call to flashLED()
int flashLED_Hover_sub1(int dummy) // ...this dummy argument is not used here
{
if(flagHover > 0) {
LMFD_LED2_Max();
Sleep(100);
LMFD_LED2_Min();
Sleep(100);
DeferCall(250, &flashLED_Hover_sub1, 0);
} else {
LMFD_LED2_Min();
}
}
int LMFD_LED2_Max() {GameOutput( &LMFD, OUT_ID_LED_INTENSITY, 200); GameOutput( &LMFD, OUT_ID_LED_2 , 1);}
int LMFD_LED2_Min() {GameOutput( &LMFD, OUT_ID_LED_2, 0); GameOutput( &LMFD, OUT_ID_LED_INTENSITY, 20); }
//}}}
ça m'a aussi donné l'idée d'un
minuteur permanent qui peut servir de
temporisateur dans des fonctions
Code : Tout sélectionner
int flag_timer_500msec = 0;
timer_on_off_500msec(int dummy) //{{{ flag_timer_500msec will alternatively be On and Off each 500 msec as long script is running}}}
{
flag_timer_500msec = ( flag_timer_500msec == 0 );
DeferCall(500, &timer_on_off_500msec,0) ;
}
qu'en penses-tu ? ça doit marcher aussi non ?
lecture des scripts target sous notepad++
Publié : ven. sept. 23, 2011 10:33 pm
par hellfrog
petite astuce pour faciliter la lecture des scripts target sous notepad++ :
aller dans Paramétrage / configurateur de coloration syntaxique
dans thème choisissez Blackboard
puis dans la colonne langage, choisissez c++
et en bas sous la colonne description, dans la case "ext ajouté"
frappez "tmh tmc tmm"
puis cliquez enregistrez
maintenant tte ouverture d'un fichier target sous notepad++ vous donne un fichier coloré avec la syntaxe qui ressort et un beau fond foncé.
c'est bcp plus lisible et clair.
Memes manips possibles si vous utilisez SciTe ou d'autres éditeurs...
question editeur de script
Publié : ven. sept. 23, 2011 10:43 pm
par hellfrog
un truc qui m'embête c'est la gestion des retour à la ligne entre un editeur texte ou programme habituel et l'interface target script...
j'ai pas pigé la gestion par Target Script des Tab et CR+LF
pour accepter de reconnaître un retour ligne dans une phrase de plusieurs lignes, d'avec la séparation entre des phrases différentes
ex:
Code : Tout sélectionner
MapKey(&LMFD, OSB18, EXEC("MapKey(&LMFD, BRTU, HUD_BRTU);
MapKey(&LMFD, BRTD, HUD_BRTD);
MapKey(&LMFD, CONU, HUD_DayNight);
MapKey(&LMFD, COND, HUD_COND);
MapKey(&LMFD, SYMU, HUD_SYMU);
"));
doit être reconnue comme une seule phrase...
comme dans
Code : Tout sélectionner
MapKey(&LMFD, OSB18, EXEC("MapKey(&LMFD, BRTU, HUD_BRTU); MapKey(&LMFD, BRTD, HUD_BRTD); MapKey(&LMFD, CONU, HUD_DayNight); MapKey(&LMFD, COND, HUD_COND); MapKey(&LMFD, SYMU, HUD_SYMU);"));
mais des fois ça marche des fois ça marche pas...
et ça me gave...
si qqn a une solution claire...
Publié : ven. sept. 23, 2011 11:23 pm
par ivanwfr
hellfrog a écrit :ça m'a aussi donné l'idée d'un minuteur permanent qui peut servir de temporisateur dans des fonctions
Code : Tout sélectionner
[color="DarkSlateGray"]int flag_timer_500msec = 0;[/color]
timer_on_off_500msec(int dummy)
{
[color="DarkSlateGray"] flag_timer_500msec = ( flag_timer_500msec == 0 );
[/color] [B][color="#8f8"]if(flag_X ... [/color][/B]
DeferCall(500, &timer_on_off_500msec,0) ;
}
qu'en penses-tu ? ça doit marcher aussi non ?
Bonne idée, il s'agit juste d'y ajouter l'appel des fonctions à exécuter avec le if() qui va bien pour démarrer et arrêter leur éxécution en boucle.
Un simple MapKey() pourra alors piloter les différentes séquences.
Dans ce cas, flag_timer_500msec serait remplacé par une ou plusieurs variables.
[INDENT]MapKey(&LMFD, OSB18, EXEC("flag_X = (flag_X == 0 );");
...[/INDENT]
modifier l'axe SC de +/- x% en sensibilité
Publié : ven. sept. 23, 2011 11:23 pm
par hellfrog
j'ai trouvé ce petit script très intéresant car il permet facilement de modifier la sensibilité de l'axe SC :
Code : Tout sélectionner
include "../_util/util_TargetTrimSCxy.tmc"
int main()
{
MapKeyIO(&Throttle, CSU, CHAIN(Shkval_Wide_View_7x, EXEC("Trim_WarthogSCxy_Percent(15, 7);")), KU_31_Shkval_slew_up);
MapKeyIO(&Throttle, CSD, CHAIN(Shkval_Narrow_View_23x, EXEC("Trim_WarthogSCxy_Percent(15, 2);")), KU_31_Shkval_slew_down);
}
Target\BS\_util\_util_TargetTrimSCxy.tmc :
Code : Tout sélectionner
// THRUSTMASTER TARGET SCRIPT
// (Script Editor 1.0)
//main should: include "target.tmh"
//
// ----{{{
// call in main tmc with
// include "..\_util\_util_TargetTrimSCxy.tmc";
// syntax to call the function you want to use :
// EXEC(" name of function to call ();")
// ----}}}
// **********
// functions
// **********
int curveSC_percent;
int Trim_WarthogSCxy_Percent(int [color=Yellow]DeltaPercent_Physic[/color], int [color=Orange]DeltaPercent_Sent[/color])
{
curveSC_percent = LIST(0, (50-DeltaPercent_Sent),
(50-DeltaPercent_Physic), 50,
(50+DeltaPercent_Physic), 50,
100, (50+DeltaPercent_Sent));
SetCustomCurve(&Throttle, SCX, curveSC_percent);
SetCustomCurve(&Throttle, SCY, curveSC_percent);
// BS Med shkval
// LIST(0,43, 35,50, 65,50, 100,57); === DeltaPercent_Physic = 15 ; DeltaPercent_Sent = 7
// BS Low shkval
// LIST(0,48, 35,50, 65,50, 100,52); === DeltaPercent_Physic = 15 ; DeltaPercent_Sent = 2
// LIST(0,46, 45,50, 55,50, 100,54); === DeltaPercent_Physic = 5 ; DeltaPercent_Sent = 4
// LIST(0,32, 45,50, 55,50, 100,68); === DeltaPercent_Physic = 5 ; DeltaPercent_Sent = 18
// LIST(0,40, 45,50, 55,50, 100,60); === DeltaPercent_Physic = 5 ; DeltaPercent_Sent = 10
}
Publié : ven. sept. 23, 2011 11:41 pm
par ivanwfr
Tu devrais pouvoir te passer de la macro CHAIN dans la fonction Trim_WarthogSCxy_Percent.
Le groupage des 2 appels à SetCustomCurve n'est pas nécessaire.
Publié : ven. sept. 23, 2011 11:51 pm
par hellfrog
oui tu as raison.
et pour l'éditeur ?
profil BS Warthog + MFDs
Publié : sam. sept. 24, 2011 1:17 am
par hellfrog
Publié : sam. sept. 24, 2011 3:10 am
par ivanwfr
hellfrog a écrit :oui tu as raison.
et pour l'éditeur ?
Pour une réponse argumentée, il faudrait avoir un échantillon de chaque sorte, un qui marche et un qui pose problème.
Techniquement:
- avec TARGET, on a affaire à une syntaxe "proche" de celle du langage C/C++.
- Les chaines de caractères (litteral string) sont représentées par des lettres entre guillemets.
- A l'origine du language C, elle devaient se rédiger sur une seul ligne.
- Une évolution ANSI-C autorise de les mettre sous forme de liste MAIS chaque ligne doit comporter son guillemet de début de de fin. Ce qui donnerait ça:
Code : Tout sélectionner
MapKey(
&LMFD
, OSB18
, EXEC(
"MapKey(&LMFD, BRTU, HUD_BRTU);"
"MapKey(&LMFD, BRTD, HUD_BRTD);"
"MapKey(&LMFD, CONU, HUD_DayNight);"
"MapKey(&LMFD, COND, HUD_COND);"
"MapKey(&LMFD, SYMU, HUD_SYMU);"
)
);
maintenant, si ça arrive à marcher sans, c'est que TARGET est plus tolérant et qu'il s'agit d'une histoire de CR-LF ... un truc à Microsoft ... UNIX n'a pas besoion du Carriage Return, un Line Feed suffit ... on n'est pas en train de tapper sur un machine à écrire après tout!
Faut faire des expériences ... Notepad peut surement foutre la merde avec des CR inutiles et Notepad++ peut sans doute faire comme on veut... voir les options.
Publié : sam. sept. 24, 2011 3:15 am
par ivanwfr
hellfrog a écrit :oui tu as raison.
et pour l'éditeur ?
Pour une réponse argumentée, il faudrait avoir un échantillon de chaque sorte, un qui marche et un qui pose problème.
Techniquement:
- avec TARGET, on a affaire à une syntaxe "proche" de celle du langage C/C++.
- Les chaines de caractères (litteral string) sont représentées par des lettres entre guillemets.
- A l'origine du language C, elle devaient se rédiger sur une seul ligne.
- Une évolution ANSI-C autorise de les mettre sous forme de liste MAIS chaque ligne doit comporter son guillemet de début de de fin. Ce qui donnerait ça:
Code : Tout sélectionner
MapKey(
&LMFD
, OSB18
, EXEC(
"MapKey(&LMFD, BRTU, HUD_BRTU);"
"MapKey(&LMFD, BRTD, HUD_BRTD);"
"MapKey(&LMFD, CONU, HUD_DayNight);"
"MapKey(&LMFD, COND, HUD_COND);"
"MapKey(&LMFD, SYMU, HUD_SYMU);"
)
);
maintenant, si ça arrive à marcher sans, c'est que TARGET est plus tolérant et qu'il s'agit d'une histoire de CR-LF ... un truc à Microsoft ... UNIX n'a pas besoion du Carriage Return, un Line Feed suffit ... on n'est pas en train de tapper sur un machine à écrire après tout!
Faut faire des expériences ... Notepad peut surement foutre la merde avec des CR inutiles et Notepad++ peut sans doute faire comme on veut... voir les options.
pb clignotement des LEDs des MFDs
Publié : dim. sept. 25, 2011 10:41 pm
par hellfrog
au bout de qqs secondes j'ai ce message :
flagHover>0 : flash 1
--- ça c'est un commentaire dans le script---
Error: One of the selected USB devices (2) has been unplugged. Aborting script!
Aborting script (check output above for reason)...
Script stopped!
et si sleep(delai) est avec delai en millisecondes, ça colle pas,
avec le script ci-dessous extrait de mon profil j'ai bien 5 secondes entre chaque allumage / extinction des LEDs...
donc ça marche, mais pas comme il faudrait !
et le jeu n'est meme pas lancé, j'ai windows, qqs taches de fond comme d'hab, notepad++, Target, firefox et un pdf ouvert ,c'est tout. CPU à 5% maxi !!!
Code : Tout sélectionner
int main()
{
MapKey(&Throttle, LTB, EXEC("func_Hover();"));
}
int EventHandle(int type, alias o, int x)
{
DefaultMapping(&o, x);
}
// {{{
int flagHover = 0;
// ...this is what gets EXECuted when some button is pressed
int func_Hover()
{
ActKey(KEYON+Hover_On_Off);
flagHover = (flagHover == 0); // toggle 1, 0, 1, 0, ...
if(flagHover == 1) func_Hover_flashingLED(0);
printf("func_Hover return flagHover %d\xa", flagHover);
}
// ...this is a FUNCTION THAT REPEATEDLY CALLS ITSELF after some delay
// ...as long as flagHover variable is not cleared by another call to flashLED()
int func_Hover_flashingLED(int dummy) // ...this dummy argument is not used here
{
if(flagHover > 0) {
printf("flagHover>0 : flash %d\xa", flagHover);
LMFD_LED2_Max();
Sleep(100);
LMFD_LED2_Min();
Sleep(100);
DeferCall(250, &func_Hover_flashingLED, 0);
} else {
LMFD_LED2_Min();
}
}
int LMFD_LED2_Max() {GameOutput( &LMFD, OUT_ID_LED_INTENSITY, 200); GameOutput( &LMFD, OUT_ID_LED_2 , 1);}
int LMFD_LED2_Min() {GameOutput( &LMFD, OUT_ID_LED_2, 0); GameOutput( &LMFD, OUT_ID_LED_INTENSITY, 20); }
//}}}
*****************************************************
EDIT :
modif du script :
Code : Tout sélectionner
int func_Hover_flashingLED(int dummy) // ...this dummy argument is not used here
{
if(flagHover > 0) {
printf("flagHover>0 : flash %d\xa", flagHover);
// LMFD_LED2_Max();
GameOutput( &LMFD, OUT_ID_LED_2 , 1);
Sleep(100);
// LMFD_LED2_Min();
GameOutput( &LMFD, OUT_ID_LED_2, 0);
Sleep(100);
DeferCall(25, &func_Hover_flashingLED, 0);
} else {
GameOutput( &LMFD, OUT_ID_LED_2, 0);
// LMFD_LED2_Min();
}
}
maintenant ça marche très bien !!!
conclusion : il ne faut pas jouer trop avec l'intensité ??????
(mes MFDs sont pourtant sur des HUBs alimentés, et le changement d'intensité seul avec un bouton fonctionne sans problème, c'est cumulé au clignotemetn que ça coince... bug ?)
*******************
second EDIT
Code : Tout sélectionner
// {{{
int flagHover = 0;
int flagDescent = 0;
int flagFlightDirector = 0;
int flagRoute = 0;
int flagHeading = 0;
int flagAlt = 0;
// }}}
int func_Hover(){ // {{{ L MFD Led 1 flash rapide
ActKey(PULSE+KEYON+Hover_On_Off);
flagHover = (flagHover == 0); // toggle 1, 0, 1, 0, ...
if(flagHover == 1) func_Hover_flashingLED(0);
printf("func_Hover return flagHover %d\xa", flagHover);
}
// ...this is a FUNCTION THAT REPEATEDLY CALLS ITSELF after some delay... as long as flagHover variable is not cleared by another call to func_Hover()
int func_Hover_flashingLED(int dummy) // ...this dummy argument is not used here but necessary for DeferCall syntax below
{
if(flagHover > 0) {
// LMFD_LED2_Max();
GameOutput( &LMFD, OUT_ID_LED_1 , 1);
Sleep(100);
// LMFD_LED2_Min();
GameOutput( &LMFD, OUT_ID_LED_1, 0);
Sleep(100);
DeferCall(250, &func_Hover_flashingLED, 0);
} else {
GameOutput( &LMFD, OUT_ID_LED_1, 0);
// LMFD_LED2_Min();
}
}
// int LMFD_LED2_Max() {GameOutput( &LMFD, OUT_ID_LED_INTENSITY, 200); GameOutput( &LMFD, OUT_ID_LED_2 , 1);}
// int LMFD_LED2_Min() {GameOutput( &LMFD, OUT_ID_LED_2, 0); GameOutput( &LMFD, OUT_ID_LED_INTENSITY, 20); }
//}}}
int func_Descent(){ //{{{ R MFD Leds 1 puis 2 on et off flash 80 msec repété
ActKey(PULSE+KEYON+Engage_Descent_Mode);
flagDescent = (flagDescent == 0); // toggle 1, 0, 1, 0, ...
if(flagDescent == 1) func_Descent_flashingLED(0);
printf("func_Descent return flagDescent %d\xa", flagDescent);
}
int func_Descent_flashingLED(int dummy){
if(flagDescent > 0) {
GameOutput( &RMFD, OUT_ID_LED_1 , 1);
Sleep(80);
GameOutput( &RMFD, OUT_ID_LED_1, 0);
GameOutput( &RMFD, OUT_ID_LED_2 , 1);
Sleep(80);
GameOutput( &RMFD, OUT_ID_LED_2, 0);
Sleep(80);
DeferCall(240, &func_Descent_flashingLED, 0);
} else {
GameOutput( &RMFD, OUT_ID_LED_1, 0);
GameOutput( &RMFD, OUT_ID_LED_2, 0);
}
}
// }}}
int func_FlightDirector(){ //{{{ L MFD Led 2 flash lent
ActKey(PULSE+KEYON+Autopilot_Director_control);
flagFlightDirector = (flagFlightDirector == 0); // toggle 1, 0, 1, 0, ...
if(flagFlightDirector == 1) func_FlightDirector_flashingLED(0);
printf("func_FlightDirector return flagFlightDirector %d\xa", flagFlightDirector);
}
int func_FlightDirector_flashingLED(int dummy){
if(flagFlightDirector > 0) {
GameOutput( &LMFD, OUT_ID_LED_2 , 1);
Sleep(400);
GameOutput( &LMFD, OUT_ID_LED_2, 0);
Sleep(400);
DeferCall(800, &func_FlightDirector_flashingLED, 0);
} else {
GameOutput( &LMFD, OUT_ID_LED_2, 0);
}
}
// }}}
int func_Route(){ //{{{ L MFD Led 1 allumé continu
ActKey(PULSE+KEYON+Engage_Disengage_Route_Mode);
flagRoute = (flagRoute == 0); // toggle 1, 0, 1, 0, ...
printf("func_Route return flagRoute %d\xa", flagRoute);
if(flagRoute == 1) {
GameOutput( &LMFD, OUT_ID_LED_1 , 1);
} else {
GameOutput( &LMFD, OUT_ID_LED_1, 0);
}
}
// }}}
int func_Heading(){ //{{{ L MFD Led 1 flash lent
ActKey(PULSE+KEYON+Autopilot_Desired_heading_Desired_track);
flagHeading = (flagHeading == 0); // toggle 1, 0, 1, 0, ...
if(flagHeading == 1) func_Heading_flashingLED(0);
printf("func_Heading return flagHeading %d\xa", flagHeading);
}
int func_Heading_flashingLED(int dummy){
if(flagHeading > 0) {
GameOutput( &LMFD, OUT_ID_LED_1 , 1);
Sleep(400);
GameOutput( &LMFD, OUT_ID_LED_1, 0);
Sleep(400);
DeferCall(800, &func_Heading_flashingLED, 0);
} else {
GameOutput( &LMFD, OUT_ID_LED_1, 0);
}
}
// }}}
// ALT mode()
//
int func_Alt(){ //{{{ R MFD 2 allumé continu
ActKey(PULSE+KEYON+Autopilot_Altitude_hold);
flagAlt = (flagAlt == 0); // toggle 1, 0, 1, 0, ...
printf("func_Alt return flagAlt %d\xa", flagAlt);
if(flagAlt == 1) {
GameOutput( &RMFD, OUT_ID_LED_2 , 1);
} else {
GameOutput( &RMFD, OUT_ID_LED_2, 0);
}
}
// }}}
ça le fait
aussi (message erreur MFDs déconnecté) avec la fonction func_Descent() au bout qqs secondes... !!!
[/color][/color] [/color]
autre question : pourquoi ça marche pas ?
Publié : lun. sept. 26, 2011 12:03 am
par hellfrog
dans le principal :
Code : Tout sélectionner
include "../_util/util_LEDs.tmc"
include "./BS_tm/BS_MFDs.tmc"
int main()
{
...
init_BS_MFDs();
BS_MFDs_map();
}
dans ../_util/util_LEDs.tmc :
Code : Tout sélectionner
...
int LEDS_AllOnSoft(){
GameOutput( &Throttle, OUT_ID_LED_BACKLIGHT, 1);
LEDS_flash( &Throttle, LED_Throttle_1);
LEDs_MFDs_flash_Min();
Sleep(500);
}
int LEDS_AllOff(){
GameOutput( &Throttle, OUT_ID_LED_1 , 0);
GameOutput( &Throttle, OUT_ID_LED_2 , 0);
GameOutput( &Throttle, OUT_ID_LED_3 , 0);
GameOutput( &Throttle, OUT_ID_LED_4 , 0);
GameOutput( &Throttle, OUT_ID_LED_5 , 0);
GameOutput( &LMFD, OUT_ID_LED_1 , 0);
GameOutput( &LMFD, OUT_ID_LED_2 , 0);
GameOutput( &RMFD, OUT_ID_LED_1 , 0);
GameOutput( &RMFD, OUT_ID_LED_2 , 0);
LEDS_flash( &Throttle, 0);
GameOutput( &Throttle, OUT_ID_LED_BACKLIGHT, 0);
LEDS_flash( &LMFD, 0);
LEDS_flash( &RMFD, 0);
Sleep(500);
}
int LEDs_MFDs_flash_Min(){
LEDS_flash( &LMFD, 20);
LEDS_flash( &RMFD, 20);
Sleep(100);
}
int LEDS_flash(alias o, int LedIntensity){
GameOutput(&o, OUT_ID_LED_INTENSITY, LedIntensity); Sleep(50);
}
dans ./BS_tm/BS_MFDs.tmc:
Code : Tout sélectionner
...
int Leds_Off, Leds_On;
int init_BS_MFDs(){
...
int Leds_Off = EXEC("LEDS_AllOff();");
int Leds_On = SEQ(EXEC("LEDS_AllOnSoft();"), EXEC("LEDS_flash( &LMFD, 50);LEDS_flash( &RMFD, 50);"), EXEC("LEDS_flash( &LMFD, 100);LEDS_flash( &RMFD, 100);"), EXEC("LEDS_flash( &LMFD, 150);LEDS_flash( &RMFD, 150);"), EXEC("LEDS_flash( &LMFD, 200);LEDS_flash( &RMFD, 200);"), EXEC("LEDS_flash( &LMFD, 250);LEDS_flash( &RMFD, 250);")); //}}}
}
int BS_MFDs_map()
{
MapKey(&RMFD, CONU, [color=Yellow]Leds_On[/color]); // [color=PaleGreen]EXEC("LEDS_AllOnSoft();"));[/color]
MapKey(&RMFD, COND, [color=Yellow]Leds_Off[/color]); // [color=PaleGreen]EXEC("LEDS_AllOff();"));[/color]
avec le code
en vert ça marche
avec le code
en jaune ça marche pas... pourquoi ?
réponse de Irwanfr
Publié : lun. sept. 26, 2011 12:50 am
par ivanwfr
hellfrog a écrit :dans le principal :
dans ./BS_tm/BS_MFDs.tmc:
Code : Tout sélectionner
...
[B][color=Magenta]int Leds_Off, Leds_On;[/color][/B]
int init_BS_MFDs(){
...
[color=Red][s]int[/s][/color] [B][color=Yellow]Leds_Off =[/color][/B] EXEC("LEDS_AllOff();");
[color=Red][s]int[/s][/color] [B][color=Yellow]Leds_On =[/color][/B] SEQ(EXEC("LEDS_AllOnSoft();"), EXEC("LEDS_flash( &LMFD, 50);LEDS_flash( &RMFD, 50);"), EXEC("LEDS_flash( &LMFD, 100);LEDS_flash( &RMFD, 100);"), EXEC("LEDS_flash( &LMFD, 150);LEDS_flash( &RMFD, 150);"), EXEC("LEDS_flash( &LMFD, 200);LEDS_flash( &RMFD, 200);"), EXEC("LEDS_flash( &LMFD, 250);LEDS_flash( &RMFD, 250);")); //}}}
}
int BS_MFDs_map()
{
MapKey(&RMFD, CONU, [color=Yellow]Leds_On[/color]); // [color=PaleGreen]EXEC("LEDS_AllOnSoft();"));[/color]
MapKey(&RMFD, COND, [color=Yellow]Leds_Off[/color]); // [color=PaleGreen]EXEC("LEDS_AllOff();"));[/color]
avec le code
en vert ça marche
avec le code
en jaune ça marche pas... pourquoi ?
Il va suffire d'enlever les
int en rouge.
- Il s'agit bien comprendre la différence entre déclaration et initialisation.
- Dans la fonction init_BS_MFDs(), la ligne int LEDs_Off = ... déclare une nouvelle variable qui porte le même nom que celle déclarée au dessus.
- La première est une variable globale alors que la seconde est locale à la fonction init_BS_MFDs().
- Tu n'as donc pas initialisé les variables déclarées globalement, celles qui sont utilisées dans ta fonction BS_MFDs_map().
- Elles sont donc restées vides.
Publié : lun. sept. 26, 2011 1:07 am
par hellfrog
oups...
tellement gros que je l'ai pas vu !
merci !
c'est l'inconvénient des copier coller pour gagner du temps et éviter les fautes de frappe...
j'ai mis à jour le pb des LEDs, encore du nouveau...
me semble être un bug du driver ça non ?
Publié : lun. sept. 26, 2011 2:15 am
par ivanwfr
Oui, ça y ressemble mais les bugs servent assez souvent à mettre les erreurs sur le dos du voisin.
Il faudrait mettre de prints avant chaque opération élémentaire pour isoler celle qui provoque la déconexion...
Publié : lun. sept. 26, 2011 8:06 am
par hellfrog
Publié : lun. sept. 26, 2011 9:56 pm
par hellfrog
le pb avec les boucles qui s'appellent, c'est que si on les multiplie et qu'elles contiennent des sleep(), le script devient très peu réactif...
à utiliser avec parcimonie !
question fonction spawn
Publié : lun. sept. 26, 2011 10:06 pm
par hellfrog
comment utiliser spawn dans une fonction en lui passant des variables path et filename ?
system("spawn -w \"C:\Users\christophe_admin\Documents\Target\scripts\BS\alerts\" \"C:\\Users\\christophe_admin\\Documents\\Target\\scripts\\BS\\alerts\\Hover.wav\"");
=>
EXEC("play_Msg(path_alerts, "Hover.wav");");
et
int play_Msg(alias path, alias filename){
system("spawn -w \"&path"\"&filename"");
}
mais c'est pas la bonne syntaxe evidemment...
Publié : mar. sept. 27, 2011 4:32 pm
par ivanwfr
Voilà ce que j'ai pu tirrer du manuel
(gaffe aux espaces en trop page 35):
- une version avec répertoire de travail
- une autre sans
Code : Tout sélectionner
alias chrome_folder = "C:/Users/ivan/AppData/Local/Google/Chrome/Application";
alias chrome_path = "C:/Users/ivan/AppData/Local/Google/Chrome/Application/chrome.exe";
alias chrome_arg = "--enable-file-cookies";
H2U_UI = EXEC("spawn_folder_path_arg(&chrome_folder, &chrome_path, &chrome_arg);");
H2D_UI = EXEC("spawn_path_arg( &chrome_path, &chrome_arg);");
MapKeyIOUMD(&Joystick, H2U, H2U_UI, H2U_UO, H2U_MI, H2U_MO, H2U_DI, H2U_DO);
MapKeyIOUMD(&Joystick, H2D, H2D_UI, H2D_UO, H2D_MI, H2D_MO, H2D_DI, H2D_DO);
int spawn_path_arg(alias path, alias arg) {
printf("spawn_path_arg(%s, %s)\xa", &path, &arg);
char cmd; Dim(&cmd, 1024);
sprintf(&cmd, "spawn \"%s\" \"%s\"", &path, &arg);
printf("...system(%s)\xa", &cmd);
system( &cmd );
}
int spawn_folder_path_arg(alias folder, alias path, alias arg) {
printf("spawn_folder_path_arg(%s, %s, %s)\xa", &folder, &path, &arg);
char cmd; Dim(&cmd, 1024);
sprintf(&cmd, "spawn -w \"%s\" \"%s\" \"%s\"", &folder, &path, &arg);
printf("...system(%s)\xa", &cmd);
system( &cmd );
}
Publié : mar. sept. 27, 2011 11:07 pm
par hellfrog
j'ai un petit soucis pour utiliser ton script
je voudrais que les alias soient des variables ou que l'on puisse y concaténer des chaines
pour passer un nom de fichier comme variable texte à la fonction...
dans ton ex l'alias est une constante
si je fais
int path = "c:/truc/bidule/";
int file_name = "nomfichier.wav";
alias file_path = path & file_name ;
ça va pas
ou alors c'est que c'est pas la bonne syntaxe pour concaténer en C
comment s'y prendre ?
Publié : mar. sept. 27, 2011 11:56 pm
par hellfrog
j'ai qd meme un pb
cette simple chaine ne semble pas marcher
system("spawn -w \"C:\\Users\\christophe_admin\\Documents\\Target\\scripts\\BS\\BS_Sound\"\"C:\\Users\\christophe_admin\\Documents\\Target\\scripts\\BS\\BS_Sound\\Windows Hardware Insert.wav\"");
j'ai plutot le son windows notify.wav et il n'est pas dans le script
par contre pas d erreur de compil, de script ou d'execution
sinon sprintf concatene les chaines dans un tableau c'est ça ?
et il faut pour spawn que les chaines finissent et commencent par : \" c'est ça ?