La Place des Développeurs UFO de 10 lignes basic à l'ASM Programmation d'UFO en ASM par un nul
Reprise du message précédent
Donc, si je lis bien le code, VAR_TIMING (du moins le contenu de cette adresse... ) va s'incrémenter régulièrement (lors d'une interruption via le détournement du hook).Mais à quelle fréquence ? Au vu du code, j'opterais pour 50 Hz, mais je n'en mettrais pas ma main à couper.
Je ne saisis d'ailleurs pas trop l'intérêt présentement d'une gestion du temps, j'aurais pensé qu'elle serait appelée pour la musique mais je n'en ai pas l'impression...
MSX un jour, MSX toujours !
Cette routine peut être utilisée de 2 manières :
1 - comme Venom l'indique, à un moment, on consulte la valeur de VAR_TIMING et on la stocke dans TEMPS_DEBUT. Plus tard, on consulte à nouveau la valeur de VAR_TIMING et on la stocke dans TEMPS_FIN. On effectue le calcul TEMPS_ECOULE = TEMPS_FIN - TEMPS_DEBUT. Si TEMPS_ECOULE >= 1 s, on lance ROUTINE_1.
Par exemple, cela peut nous servir pour afficher la valeur d'un ennemi que le joueur a shooté pendant 3 secondes.
Cela peut également servir à obtenir un programme qui tourne avec le plus régulièrement possible. Au début de la boucle de jeu, on utilise TEMPS_DEBUT = VAR_TIMING. On effectue la gestion du clavier, du joueur, des ennemis, des collisions, de la musique, des sons... Juste avant de boucler, on va attendre que VAR_TIMING - TEMPS_DEBUT >= 0,5 seconde.
Pourquoi >= et pas tout simplement = ?
Il est toujours plus prudent de vérifier également que l'on a pas dépassé la valeur. Des modifications du programme peuvent le rendre plus long que prévu dans certaines conditions. On cherche un TEMPS_ECOULE = 1000 et en fait, il est déjà à 1001...
J'ai laissé = et ça fonctionne... le programme est juste un peu long. C'est pas un peu foireux cette méthode ?
Le principe de la méthode est bon. Cela dépend encore une fois de son utilisation. VAR_TIMING à force d'être incrémenté dans la routine INTERRUPTION: va finir par repasser à 0 puis à la valeur recherchée (Si VAR_TIMING contient 0xFF, l'incrémenter va faire passer sa valeur à 0x00). Du coup, le temps écoulé va être beaucoup plus long. Si par exemple, si on visait TEMPS_FIN - TEMPS_DEBUT = 0x10 (valeur hexa). Le temps écoulé obtenu serait 17x plus long. Là, on sent tout de suite une différence.
2 - Tout naturellement, on arrive à une seconde méthode. On met dans le programme principal, la variable VAR_TIMING à 0. Puis lorsque cette variable VAR_TIMING va dépasser la valeur "clé", on effectue notre action.
Dans le cadre de la boucle principale de notre programme, au début de la boucle, on met VAR_TIMING à 0. On gère le décor, le joueur, les ennemis, la musique, les bruits... Puis, on va attendre que VAR_TIMING >= valeur clé et on va repartir au début de la boucle principale où VAR_TIMING va être remis à 0.
Par contre, comme la variable VAR_TIMING est remise à zéro, elle ne peut servir qu'à une seule tâche. Je veux dire par là que vous ne pouvez pas vous en servir pour l'affichage provisoire d'un score et la temporisation du jeu. Du moins pas directement... Si vous remettez plusieurs fois à 0 entre 2 mesures, le calcul est faussé.
EDIT - j'avais fait une faute d'attention. La boucle de temps est bien sûr sur 1 octet. Edité par KN2000 Le 20/08/2010 à 16h53
1 - comme Venom l'indique, à un moment, on consulte la valeur de VAR_TIMING et on la stocke dans TEMPS_DEBUT. Plus tard, on consulte à nouveau la valeur de VAR_TIMING et on la stocke dans TEMPS_FIN. On effectue le calcul TEMPS_ECOULE = TEMPS_FIN - TEMPS_DEBUT. Si TEMPS_ECOULE >= 1 s, on lance ROUTINE_1.
Par exemple, cela peut nous servir pour afficher la valeur d'un ennemi que le joueur a shooté pendant 3 secondes.
Cela peut également servir à obtenir un programme qui tourne avec le plus régulièrement possible. Au début de la boucle de jeu, on utilise TEMPS_DEBUT = VAR_TIMING. On effectue la gestion du clavier, du joueur, des ennemis, des collisions, de la musique, des sons... Juste avant de boucler, on va attendre que VAR_TIMING - TEMPS_DEBUT >= 0,5 seconde.
Pourquoi >= et pas tout simplement = ?
Il est toujours plus prudent de vérifier également que l'on a pas dépassé la valeur. Des modifications du programme peuvent le rendre plus long que prévu dans certaines conditions. On cherche un TEMPS_ECOULE = 1000 et en fait, il est déjà à 1001...
J'ai laissé = et ça fonctionne... le programme est juste un peu long. C'est pas un peu foireux cette méthode ?
Le principe de la méthode est bon. Cela dépend encore une fois de son utilisation. VAR_TIMING à force d'être incrémenté dans la routine INTERRUPTION: va finir par repasser à 0 puis à la valeur recherchée (Si VAR_TIMING contient 0xFF, l'incrémenter va faire passer sa valeur à 0x00). Du coup, le temps écoulé va être beaucoup plus long. Si par exemple, si on visait TEMPS_FIN - TEMPS_DEBUT = 0x10 (valeur hexa). Le temps écoulé obtenu serait 17x plus long. Là, on sent tout de suite une différence.
2 - Tout naturellement, on arrive à une seconde méthode. On met dans le programme principal, la variable VAR_TIMING à 0. Puis lorsque cette variable VAR_TIMING va dépasser la valeur "clé", on effectue notre action.
Dans le cadre de la boucle principale de notre programme, au début de la boucle, on met VAR_TIMING à 0. On gère le décor, le joueur, les ennemis, la musique, les bruits... Puis, on va attendre que VAR_TIMING >= valeur clé et on va repartir au début de la boucle principale où VAR_TIMING va être remis à 0.
Par contre, comme la variable VAR_TIMING est remise à zéro, elle ne peut servir qu'à une seule tâche. Je veux dire par là que vous ne pouvez pas vous en servir pour l'affichage provisoire d'un score et la temporisation du jeu. Du moins pas directement... Si vous remettez plusieurs fois à 0 entre 2 mesures, le calcul est faussé.
EDIT - j'avais fait une faute d'attention. La boucle de temps est bien sûr sur 1 octet. Edité par KN2000 Le 20/08/2010 à 16h53
Nous sommes en 2010 aps JC, toute la Gaule est envahie. Ah ben non, apparement, un village résiste encore aux envahisseurs Personalcomputerum et autres Consoledessalum. Bienvenue dans l'antre du emessix !
Je ne pige toujours pas l'intérêt dans le programme ici... Après test, je remplace dans la boucle principale l'appel à GST_TIMING par un halt et ça tourne pareil...
EDIT : Ah non, c'est plus lent en fait... Ce serait donc un système pour la gestion de "frames" en gros
EDIT : Ah non, c'est plus lent en fait... Ce serait donc un système pour la gestion de "frames" en gros
MSX un jour, MSX toujours !
Rhaaa, moi aussi, je bloque. C'est compliqué à déméler. (Osaure reviens ). Je crois que Osaure a dû rencontrer ce problème où VAR_TIMING revient à 0 trop rapidement. Et du coup, il essaie de rallonger l'intervalle ??? Mais là, je ne suis pas trop sûr...
Sinon, c'est bien calé sur le 50 Hz ou le 60 Hz suivant que l'on utilise un MSX européen ou japonais. Enfin, comme on a pas mal de MSX modifiés, ce n'est plus trop fiable. Il faut vérifier la valeur de VDP(10).
En 50 Hz (Europe), on a une interruption tous les 1/50 de seconde.
En 60 Hz (Japon), on a une interruption tous les 1/60 de seconde. Les jeux qui utilisent cette méthode de synchronisation sont plus rapides en 60 Hz qu'en 50. Les musiques semblent un peu différentes (car jouées plus rapidement).
EDIT : Euréka.
VAR_TIMING s'incrémente tous les 1/50 de seconde (en 50 Hz)
Pour stabiliser son programme, MSXOsaure prend une valeur fixe (égale à 50) et lui retire la valeur de VAR_TIMING. Il se sert du résultat pour augmenter ou diminuer le nombre de fois qu'il éxécute sa boucle @@time2:. Et il remet VAR_TIMING à 0 : XOR A - LD (VAR_TIMING),A.
Par contre, VAR_TIMING va s'incrémenter pendant l'éxécution de la boucle @@time: (et la boucle @@time2: qui lui est intégrée). Du coup, je crains que les calculs soient faussées. Il vaudrait mieux remettre VAR_TIMING à 0 juste avant le call GST_VISEUR c'est à dire en tête de la boucle principale.
Sur le principe, l'idée est bonne. Plus les différentes gestions auront été longues, plus VAR_TIMING sera élevé et donc plus 50-VAR_TIMING sera petit et du coup, la boucle @@time: prendra peu de temps.
A l'inverse, si les gestions diverses ont pris peu de temps, VAR_TIMING sera peu élevé. 50 - VAR_TIMING va donner une valeur plus importante et du coup, @@time pendra plus de temps à être éxécutée.
Mais, car hélas il y a un mais, je ne suis pas sûr que ce soit bien synchronisé, en définitive. Il faudrait que le temps nécessaire à éxécuter les gestions "viseur" à "son explosion" + la gestion timing soit toujours le même ! Il faudrait grosso-modo que @@time soit équivalent à 1/50 de seconde.
EDIT 2 : Au sujet de INTERRUPTION.
Plus simplement, on peut considérer qu'il s'agit d'un chronomètre. VAR_TIMING nous donnant une valeur de temps. Edité par KN2000 Le 18/08/2010 à 12h09
Sinon, c'est bien calé sur le 50 Hz ou le 60 Hz suivant que l'on utilise un MSX européen ou japonais. Enfin, comme on a pas mal de MSX modifiés, ce n'est plus trop fiable. Il faut vérifier la valeur de VDP(10).
En 50 Hz (Europe), on a une interruption tous les 1/50 de seconde.
En 60 Hz (Japon), on a une interruption tous les 1/60 de seconde. Les jeux qui utilisent cette méthode de synchronisation sont plus rapides en 60 Hz qu'en 50. Les musiques semblent un peu différentes (car jouées plus rapidement).
EDIT : Euréka.
VAR_TIMING s'incrémente tous les 1/50 de seconde (en 50 Hz)
Pour stabiliser son programme, MSXOsaure prend une valeur fixe (égale à 50) et lui retire la valeur de VAR_TIMING. Il se sert du résultat pour augmenter ou diminuer le nombre de fois qu'il éxécute sa boucle @@time2:. Et il remet VAR_TIMING à 0 : XOR A - LD (VAR_TIMING),A.
Par contre, VAR_TIMING va s'incrémenter pendant l'éxécution de la boucle @@time: (et la boucle @@time2: qui lui est intégrée). Du coup, je crains que les calculs soient faussées. Il vaudrait mieux remettre VAR_TIMING à 0 juste avant le call GST_VISEUR c'est à dire en tête de la boucle principale.
Sur le principe, l'idée est bonne. Plus les différentes gestions auront été longues, plus VAR_TIMING sera élevé et donc plus 50-VAR_TIMING sera petit et du coup, la boucle @@time: prendra peu de temps.
A l'inverse, si les gestions diverses ont pris peu de temps, VAR_TIMING sera peu élevé. 50 - VAR_TIMING va donner une valeur plus importante et du coup, @@time pendra plus de temps à être éxécutée.
Mais, car hélas il y a un mais, je ne suis pas sûr que ce soit bien synchronisé, en définitive. Il faudrait que le temps nécessaire à éxécuter les gestions "viseur" à "son explosion" + la gestion timing soit toujours le même ! Il faudrait grosso-modo que @@time soit équivalent à 1/50 de seconde.
EDIT 2 : Au sujet de INTERRUPTION.
Plus simplement, on peut considérer qu'il s'agit d'un chronomètre. VAR_TIMING nous donnant une valeur de temps. Edité par KN2000 Le 18/08/2010 à 12h09
Nous sommes en 2010 aps JC, toute la Gaule est envahie. Ah ben non, apparement, un village résiste encore aux envahisseurs Personalcomputerum et autres Consoledessalum. Bienvenue dans l'antre du emessix !
Bon, je me lance... Voici une proposition de modification :
sans oublier
EDIT
Après les tests de Granced, on va laisser pour l'instant, la valeur à 1. Car il semble que le programme est assez rapide pour effectuer une boucle entre 1 à 2 interruptions.
Comme indiqué par Venom, une interruption en mode 60 Hz intervient toutes les 16ms environ (toutes les 20ms en mode 50 Hz). Edité par KN2000 Le 18/08/2010 à 16h21
Code ASM :
;---------------- GST_TIMING: ;---------------- @@time: LD A,[VAR_TIMING] CP 1 ; notre valeur clé JR C,@@time ; la boucle vers @@time se fera tant que VAR_TIMING < 50 RET
sans oublier
Code ASM :
; ; Boucle principale ; LOOP: XOR A ; On met le Registre A à la valeur 0 LD [VAR_TIMING],A ; Ajout permettant la remise à zéro du compteur CALL GST_VISEUR ; on reprend le code de Osaure
EDIT
Après les tests de Granced, on va laisser pour l'instant, la valeur à 1. Car il semble que le programme est assez rapide pour effectuer une boucle entre 1 à 2 interruptions.
Comme indiqué par Venom, une interruption en mode 60 Hz intervient toutes les 16ms environ (toutes les 20ms en mode 50 Hz). Edité par KN2000 Le 18/08/2010 à 16h21
Nous sommes en 2010 aps JC, toute la Gaule est envahie. Ah ben non, apparement, un village résiste encore aux envahisseurs Personalcomputerum et autres Consoledessalum. Bienvenue dans l'antre du emessix !
Pas trop le temps d'éplucher mon programme, j'ai un peu bricolé et j'avoue que je n'étais pas sur du résultat pour ce "Timer". Mais le but est bien d'avoir un programme "stabilisé" et d'éviter des accélérations et des ralentissements.
Il existe une solution pour détecter le 50 ou 60Hz je vous invite à éplucher le programme de démineur fourni avec la dernière version de ASMSX, je m'en suis beaucoup servi pour mon programme!
Et maintenant (ou plutôt demain) vacances
pour la route
Il existe une solution pour détecter le 50 ou 60Hz je vous invite à éplucher le programme de démineur fourni avec la dernière version de ASMSX, je m'en suis beaucoup servi pour mon programme!
Et maintenant (ou plutôt demain) vacances
pour la route
Le MSXien le plus à l'ouest ... ou presque
Répondre
Vous n'êtes pas autorisé à écrire dans cette catégorie