Sponsors

FacebookTwitterGoogle Bookmarks

La mantisse répond à des normes très précises que l’on peut trouver dans les docs spécialisées. En principe le bit 31 est toujours mis et la mantisse correspond en fait à une fraction plus grande que 1 2 mais plus petite que 1. Attention 0 est considéré comme un nombre positif! En ce qui concerne les livres, il n’y a aucune hésitation possible : il faut se procurer les Amiga Rom Kernel Manual édités aux Etats-Unis par la firme Addison- Wesley. Ces ouvrages n’ont que deux défauts. Le premier est qu’il sont écrits en américain. Mais ne vous découragez pas le texte est écrit de manière très simple. A titre d’exemple, avant de posséder ces ouvrages je ne comprenais rien à l’anglais et pourtant j’ai pu m’en tirer sans problème avec un simple dictionnaire même pas très épais. J’en profite pour me défouler : si un éditeur français avait la bonne idée de traduire ces ouvrages, on aurait pour une fois l’air moins bête que les autres. Quand je pense que les Amiga Rom Kernel Manual existent depuis belle lurette en allemand ! Deuxième défaut : on ne peut se procurer ces livres que chez les très bons revendeurs informatique. Autant vous prévenir de suite, c’est dur (j’ai trouvé les miens chez Mad). Par contre ces livres sont remarquables par leur exhaustivité, leurs programmes d’exemples, leur clarté, leur côté très “professionnel” etc. Les volumes les plus intéressants pour le programmeur sont “Libraries and Devices” et “Includes and Autodocs”. Munis de ces livres il est possible avec peu d’efforts de développer des programmes d’enfer et des applications géantes. En ce qui concernent les livres français (d’un prix quasi identique aux précédents !!!), ils ne méritent même pas d’être cités. Ces ouvrages parlent de tout et de rien, sont d’une qualité déplorable et truffés d’erreurs. Avec des trucs pareils il n’est plus possible de développer que de micro-applications. On vous aura prévenu ! Question : Je possède depuis peu un Amiga 500 à la place du bon vieux CBM64 que j’avais déjà depuis pas mal de lunes. Comme je programmais en langage machine, je me suis donc acheté le “Devpac 2” et quelques livres sur le processeur 68000 et F Amiga lui même. 11 ne me manquait plus qu’une revue sérieuse et j’ai choisi “Commodore Revue”. Bravo à toute l’équipe. Je me permets maintenant de vous soumettre mes petits problèmes.

Click image to download PDF

AMIGA NEWS TECH numero 14 (07-08-1990)

Document sans nom , . V : ,lv-' TRANSACTOR
AOUT 90
Le blitter (suite et fin)
Frédéric Mazué
Animation de sprites sous IRQ
Dominique Genot
REQUESTER ' ! V
Par Frédéric Mazue
EDITO
ASSEMBLEUR 68000
Application : un lecteur d'images IFF
GFA BASIC
Le Master Mind
Dominique Lorre
LANGAGE C
Le 3D en perspective
Pascal Amiable
AMIGA DOS
Initiation et Application p. 60
Dominique Lorre
Ah quelle satisfaction ! En ce moment le courrier déferle à l’ANT. Nous nous plaisons à penser que vous appréciez les efforts que nous sommes en train de faire pour corriger nos défauts. Aussi, au nom de toute l’équipe, je vous remercie pour cet abondant courrier.
Mais voilà le courrier, il faut y répondre. Pour l’instant sachez que je ne peut répondre à tous individuellement pour des raisons matérielles et il me faut donc “sélectionner” les lettres dont le contenu me paraît le plus profitable aux lecteurs. Ceci sans aucun favoritisme ni volonté de me faire personnellement plaisir, c’est promis. Souvent je trouve une question du type: “si je branche sur mon Amiga la carte GAGA elle-même connectée à la carte PROUT + elle-même en branchement permanent avec mon fer à dessouder, mon Amiga explosera-t-il dans le 68000 ou bien dans le lecteur 5 1 4 que je viens de me bricoler ?”
Je n’éxagère qu’à peine, le système D français n’est pas une légende ! Il n’est pas question actuellement de répondre à ce type de question tout simplement parce que nous ne possédont pas toutes les cartes et leurs versions béta, delta, débuga en stock. Alors qui peut répondre à ce type de question ? Tout simplement le revendeur de matériel informatique. Si celui-ci ne peut pas répondre c’est tout simplement parce qu’il est incompétent dans son métier et dans ce cas n’hésitez pas à changer de revendeur. Enfin je rappelle que l'ANT se veut être un cahier de programmation, aussi ne soyez plus étonnés si vous vous apercevez que j'ai fait quelques coupes sombres dans votre courrier. Tout ceci étant précisé, on attaque...
F. MAZUE
Découvrez Amos, le créateur de jeux dans le numéro de septembre.
]_[
REQUESTER
Question : Voilà que je reçois mon “hebdo” (NDLR : c’est un mensuel !) Favori (n° 22 déjà) et possesseur du logiciel : “Scult-animate 3D”, quelle ne fut pas ma surprise de trouver à la page 74 (rubrique IMAGE) un exemple avec les posibilités de SA3D (ou SA4D) en l’occurrence ici une balle de golf. Ge logiciel étant d’une utilisation assez complexe, que de trouvailles avec cet exemple. Quel enrichissement de manipulation, grâce surtout à une explication simple, claire et précise comprise de beaucoup (et pas seulement “les gros bras”). BRAVO POUR CE PAPIER. Mais une question subsiste : Pourrait-on imaginer dans cette rubrique IMAGE, retrouver chaque mois un exemple aussi complet pour utiliser SA3D ??? Voilà une idée parmi d’autres : chaque mois choisir un exemple pour manipuler un maximum des nombreuses fonctions de SA3D et pourquoi ne pas traiter, après quelques dessins l’animation 3D ? Avec un système équivalent, votre journal ne serait que mieux encore (il l’est déjà amplement) et pourrait décider certains de vos lecteurs à se lancer dans la 3D. Pourquoi ne pas commencer avec DpaintlII, moins fastidieux (ce n’est pas de la 3D, bien que parfois les effets soient très proches à l’œil nu), mais cela pourrait nous éduquer à l’assimilation des dessins 2D, de ses possibilités extraordinaires et à l’animation. J’attends avec impatience votre réponse quelle qu’elle soit et continue à lire votre formidable journal avec autant de plaisir.
Bastard Laurent (St-Georges-d’Orques)
Réponse : Dans le mille !!! Tout d’abord merci pour tous ces compliments ! Je me suis moi-même régalé avec l’article dont vous parlez et qui était un peu destiné à tâter le terrain. Nous avons en effet un projet qui devrait voir le jour très bientôt. Nous avons l’intention de rajouter beaucoup de pages dans TANT et donc d’ouvrir de nouvelles rubriques. Parmi celles-ci : des trucs et des astuces pour l’utilisation des logiciels complexes mais ô combien puissants du type SA4D, DpaintlII, Pro-Page, Pro-Vidéo Titler... Nous sommes convaincus que ceci plaira à beaucoup de lecteurs.
O
Question : Je suis très intéressé par la programmation du 68000 et des librairies et je suis attentivement tous vos articles les concernant. A ce sujet, l’article de D. Genot sur le traitement des nombres à virgule flottante me paraît très instructif. Serait-il possible de publier quelques routines en assembleur permettant par exemple de faire la conversion flottant-ascii ou ascii-flottant ou d’évaluer des expressions algébriques simples comme 2.718 au carré ? Quel est le format de ces nombres à virgule flottante ? Quel livre traitant des libraries mathématiques et des autres me conseillez-vous ?
Réponse : Ah les libraries mathématiques ! Voilà un sujet qui a plutôt tendance à effrayer, mais à tort : c’est plus simple qu’il n’y paraît avec de la bonne documentation. Pour ce qui est des articles à venir, nous avons pris bonne note. Disons très succinctement qu’un nombre à virgule flottante est codé sur 32 bits comme suit :
- bits 0-6 exposant de correction
- bit 7 signe du nombre (0 -> positif)
- bits 8-31 mantisse du nombre.
La mantisse répond à des normes très précises que l’on peut trouver dans les docs spécialisées. En principe le bit 31 est toujours mis et la mantisse correspond en fait à une fraction plus grande que 1 2 mais plus petite que 1. Attention 0 est considéré comme un nombre positif!
En ce qui concerne les livres, il n’y a aucune hésitation possible : il faut se procurer les Amiga Rom Kernel Manual édités aux Etats-Unis par la firme Addison- Wesley. Ces ouvrages n’ont que deux défauts. Le premier est qu’il sont écrits en américain. Mais ne vous découragez pas le texte est écrit de manière très simple. A titre d’exemple, avant de posséder ces ouvrages je ne comprenais rien à l’anglais et pourtant j’ai pu m’en tirer sans problème avec un simple dictionnaire même pas très épais. J’en profite pour me défouler : si un éditeur français avait la bonne idée de traduire ces ouvrages, on aurait pour une fois l’air moins bête que les autres. Quand je pense que les Amiga Rom Kernel Manual existent depuis belle lurette en allemand ! Deuxième défaut : on ne peut se procurer ces livres que chez les très bons revendeurs informatique. Autant vous prévenir de suite, c’est dur (j’ai trouvé les miens chez Mad). Par contre ces livres sont remarquables par leur exhaustivité, leurs programmes d’exemples, leur clarté, leur côté très “professionnel” etc. Les volumes les plus intéressants pour le programmeur sont “Libraries and Devices” et “Includes and Autodocs”. Munis de ces livres il est possible avec peu d’efforts de développer des programmes d’enfer et des applications géantes. En ce qui concernent les livres français (d’un prix quasi identique aux précédents !!!), ils ne méritent même pas d’être cités. Ces ouvrages parlent de tout et de rien, sont d’une qualité déplorable et truffés d’erreurs. Avec des trucs pareils il n’est plus possible de développer que de micro-applications. On vous aura prévenu !
O
Question : Je possède depuis peu un Amiga 500 à la place du bon vieux CBM64 que j’avais déjà depuis pas mal de lunes. Comme je programmais en langage machine, je me suis donc acheté le “Devpac 2” et quelques livres sur le processeur 68000 et F Amiga lui même. 11 ne me manquait plus qu’une revue sérieuse et j’ai choisi “Commodore Revue”. Bravo à toute l’équipe. Je me permets maintenant de vous soumettre mes petits problèmes.
jDBtülD HBBI3
- J’ai du mal à comprendre les appels des ‘library. Pouvez-vous pour les débutants de mon espèce donner les marches à suivre pour accéder au système.
- Existe-t-il un logiciel qui permet de dessiner des sprites et des bobs ? Ou y a t-il une astuce pour dessiner des bobs et sprites à l’aide de “objedit” de la disquette "extras 1.3” mais en basse résolution ?
- Dans un programme basic, comment appeler un sous-programme en langage machine fait sur ‘Devpac 2'. J’aurais encore bien d'autres questions à vous poser, mais je pense qu’il n’y a pas que moi qui ai des problèmes, alors je cède la place à un autre Amigaman qui s’arrache les cheveux lui aussi.
Hurtel Patrick (Vichy).
Réponse : Bravo pour le choix de Devpac, voilà un lecteur qui a du goût. Ah ces fameuses librairies ! Mais pas de panique c’est extrêmement simple. Vous avez à tout moment dans les pages de l'ANT des exemples d’ouvertures, utilisation puis fermeture des librairies.
Ce qui semble poser problème c’est le concept de “libraries”. Pourquoi ne pas appeler les fonctions en ROM directement comme sur un vieil ordinateur 8 bits ? Tout simplement parce que l’Amiga est multi-tâches et son système d’exploitation a besoin de savoir qui fait quoi. Ouvrir une librairie revient à demander à l’ordinateur la permission d’utiliser un paquet de fonctions de son système et c'est tout. Simple formalité un peu comme celle qui consiste à frapper à une porte pour obtenir la permission d’entrer.
En ce qui concerne les sprites et le bobs, ceci relève de l’étude de la “graphies.library". il faut y passer. Attention, quelque soit l'écran un sprite est toujours en basse résolution. Pour l’appel des sous-programmes depuis le basic, ceci est expliqué dans le manuel à la fonction Call. Mais ce qui n 'est pas dit et qui est une condition sine qua non pour un bon fonctionnement est que la routine en assembleur doit être écrite en code relatif au PC, sinon gare au Gourou. Il faut également imposer une adresse de chargement à la routine. Cette façon de faire est déplorable et contre nature vis-à-vis de l’Amiga (cf. Article de Max “apprenez-lui le caniveau ’). Alors un conseil : apprenez le langage C qui est LE langage de l’Amiga et qui est beaucoup plus facile que l’on ne le croit généralement.
O
Question : En lisant votre dernier numéro (le 22), j’ai eu envie de vous écrire et vous avez de la chance car vous ôtes le premier journal informatique auquel j’écris et dont la lettre n’est pas remplie de reproches, d’insultes.... Enfin bon, j’ai quelque chose à vous dire et à vous demander (et ne croyez pas que je ne vous insulte pas parce que j’ai des choses à vous demander) (NDLR : là j’ai pas tout compris) Bon alors commen- çons.
J’ai remarqué que dans une publicité qui passe dans votre journal, une boîte vend des logiciels du domaine public (j’ai bien dit VEND), SCAP (p.16). Je ne comprend pas comment sous prétexte qu’il y a peu de boîtes qui en fournissent, ils se permettent de vendre des logiciels qu’ils ont eu pour une somme nulle. Le seul prix acceptable pour ces disquettes est celui du support soit 7 ou 8 francs et s’ils se cachent derrière le prix de la copie, ils n’ont qu’à laisser un logiciel de copie dans une bécane pour que les acheteurs fassent leurs copies eux-mêmes.
Maintenant je voudrais vous féliciter d’utiliser la PAO. Au moins maintenant quand on tape un programme on a davantage de chances pour qu’il fonctionne. (NDLR : c’est aussi notre avis)
Dans une majorité de vos programmes assembleur de l'ANT, vous utilisez un certain nombre de Library, seulement voilà je n’en possède que très peu et rarement celles que vous utilisez. Alors je voudrais savoir comment me les procurer rapidement.
A propos de l’article “Musique Musique !” de Laurent Charbonnel, [...] je voudrais lui dire qu’il existe un logiciel qui travaille en 8 voix : Oktalyzer écrit par A. Sander.
Dans un ancien numéro vous disiez que vous alliez “tester” des revendeurs, j’attends de voir combien Général sera placé parmi les plus mauvais revendeur et parmi les plus mauvais SAV.
A la page 9 de votre dernier numéro, j’ai remarqué que Power Packer 2.38 était classé n° 7 [...] j’aimerai savoir où le trouver à moindre coût.
Grigoletto Pierre (Montrouge)
Réponse : En ce qui concerne SCAP je ne suis pas de votre avis. D’abord une disquette de bonne qualité vaut environ 15 francs. Ensuite SCAP a le mérite d’éditer un catalogue et ceci coûte" de l’argent. Enfin cela coûte également de l’argent le fait de gérer un stock de disquettes, de préparer des copies, d’immobiliser du personnel sans contre-partie d’achat, enfin le passage de son annonce. Je ne vois personnellement rien d excessif dans la pub de SCAP.
Quant à la solution que chacun vienne faire sa petite
copie, je n'ose pas imaginer le b qui en résulterait.
De plus vous pouvez toujours aller voir ailleurs...
Cher lecteur, j’ai la joie de vous informer que vous possédez toutes les librairies dont nous parlons. Elles sont soit SUR la disquette Workbench, soit DANS l’Amiga lui-même. Et il n’est même pas besoin de préciser à l’ordinateur où se trouve la librairie, il va la trouver tout seul comme un grand. Puis-je vous suggérer de lire l’ANT et VOTRE manuel plus attentivement.
Ici à Commodore Revue nous sommes bien placés pour avoir vent des nouveautés et nous connaissons Oktalyzer. Mais nous nous demandons un petit peu où vous avez acheté le vôtre celui-ci n’étant disponible
qu’en Allemagne. Edité par (99 DM) ?
Beaucoup de lecteurs attendent en effet notre liste de revendeurs. Elle est en préparation. Je tiens à vous rassurer, Général n’est pas parmi les plus mauvais son chiffre d’affaires pourrait d’ailleurs le prouver. En tout cas il a une clientèle qui se satisfait de ses prix. Et si nous faisions une liste des lecteurs “Lamer” ?
Enfin je pense que le “domaine public Fred Fish” Power Packer est disponible chez SCAP (NDLR : ils ont un large catalogue...).
Aujourd’hui, nous allons nous intéresser à la capacité que possède le blitter à tracer des droites. Mais cette fois ce n'est pas tout simple, c'est même plutôt ardu au premier abord.
1
BLITTER 5e ET DERNIÈRE PARTIE
Comme d’habitude, c’est l’initialisation de BLTSIZE qui fera démarrer le blitter, La valeur dans ce registre informe le blitter de la longueur de la droite, c'est-à-dire du nombre de points allumés composants celle-ci. Si BLTSIZE est initialisé avec la valeur 0 on aura la longueur maximum de 1024 points ce qui tombe on ne peut mieux car les largeurs et hauteurs maximum d’un bitplane sont également de 1024 points.
Peut-être pensez-vous qu’une longueur de 1024 points est insuffisante si la droite est en diagonale dans un super-bitplane ?
Observez bien l’aspect d'une droite tracée par un ordinateur : ce n’est pas une droite !
En effet l’emplacement théorique d’un point d’une droite quelconque ne correspond généralement pas exactement à la position d’un pixel sur l’écran ce qui fait qu’un ordinateur (en fait dans un Amiga le Blitter) doit se contenter d’allumer un des pixels les plus proches.
Le blitter qui est une personne très ordonnée n’allume pas les pixels les plus proches n’importe comment, mais remplace de petites portions de la droite à tracer par des “marches d’escalier”.
Quelques essais permettraient de constater les choses suivantes :
- Si la droite est peu inclinée (moins de 45°) les marches de l’escalier sont horizontales.
- Si la droite est très Inclinée (plus de 45°) les marches de l’escalier sont verticales.
- Si la droite est inclinée à 45° les marches se réduisent à un point, il n’y a pas vraiment d’escalier et le tracé est presque parfait.
Tout ceci n’est pas sans conséquence :
- On remarque d’abord que la longueur exprimée en nombre de points d’une droite correspond à la différence des abscisses plus un ou à la différence des ordonnées plus un des points de départ et d’arrivée de la droite selon que la droite est plus ou moins inclinée. Ceci a pour conséquence que la longueur d’une droite ne pourra jamais éxcéder 1024 points.
- Le Blitter n’étant pas devin il faudra lui communiquer l’inclinaison de la droite à tracer.
Malheureusement le blitter ne sait pas ce que c’est qu’un angle et à la place utilise les octants. Il faut comprendre que pour le blitter un repère orthonormé est divisé en huit secteurs égaux (donc de 45°) d’où le nom d’octants. Voir la figure mais attention : le sens des Y croissants est vers le bas.
Comment faire pour savoir “à la main” dans quel octant se situe une droite ? Très simple : il suffit d’utiliser la figure en plaçant le point de départ de la droite sur L'ORIGINE DU REPERE, puis en plaçant le point d’arrivée selon ses coordonnées (attention au sens des Y). On voit ainsi dans quel octant se trouve la droite.
GENERALISATION
Si cette méthode peut à la rigueur convenir pour préparer le tracé d’une droite, elle est insupportable pour un nombre élevé de droites.
Voici comment il est possible de généraliser :
On appelle x1 ,y1 les coordonnées du point de départ de la droite et x2,y2 les coordonnées du point d’arrivée de la droite.
On appelle dx la valeur absolue de la différence des abscisses c’est-à- dire Ix2-x11 et dy la valeur absolue de la différence des ordonnées c’est- à-dire Iy2-y1l.
On a alors les relations suivantes : si x1 x2 et y1 y2 et dx dy la droite est dans l’octant 6
?7
? 5
? 4
? 1 ? 0 ? 2 ? 3
si x1 x2 et y1 y2 et dx>dy- si x1 >x2 et y1 y2 et dx dy - si x1>x2 et y1 y2 et dx>dy- si x1 x2ety1>y2etdx dy- si x1 x2 et y1 >y2 et dx>dy - si x1>x2 et y1>y2 et dx dy- si x1 >x2 et y1 >y2 et dx>dy -
Ce n’est pas tout : on ne peut pas communiquer directement un numéro d’octant au blitter. Chaque octant est en fait codé sur 3 bits d’une façon assez hermétique qu’il n’est pas très intéressant d’analyser. Voyons directement le résultat :
Octant
Code
6
1
3 7 5 2 0
4
0
J
2
3
4
5
6 7
UNE ROUTINE PRATIQUE
Toutes ces relations ne sont en fait intéressantes que si elles sont utilisées dans un programme.
Comme ma bonté n’a pas de limite vous trouverez dans le listing d’exemple une routine nommée recherchejoctant et qui en fait renvoie le code de l’octant concerné.
Cette routine peut être utilisée dans vos programmes personnels sans problème.
Son principe est simple :
Le programme comporte un tableau des codes d’octants. La routine effectue les comparaisons des relations ci-dessus et fait un décalage du flag X dans le registre D4 à chaque comparaison. A la fin D4 sert d’index pointant sur l’élément du tableau recherché. La routine effectue également un petit travail supplémentaire : elle regarde qui de dx et de dy est le plus grand puis range le résultat selon le cas dans les labels Pdelta et Gdelta ce qui sera utilisé pour l'initialisation de certains registres.
En effet tous les registres du blitter doivent être initialisés pour un tracé de droite. Le moins que l'on puisse dire est que les valeurs d’initialisation sont quelquefois bizarroïdes.
Voyons tout cela méthodiquement :
- registre BLTBDAT
Il doit contenir la valeur $ 8000. C’est-à-dire que seul le bit 15 est mis. Ce bit doit être décalé par le Blitter selon ses besoins puis l’envoyer en sortie dans BLTDDAT pour allumer les points.
- registre BLTBDAT
Il doit contenir la valeur de texture de la droite. Il faut comprendre que ce registre doit contenir une valeur de masque. Si la valeur est $ ffff la droite est on ne peut plus complète et normale. La valeur $ 0000 peut servir à tracer par effacement dans une surface colorée.
La valeur $ ff00 peut servir à tracer des pointillés. N’hésitez pas à essayer différentes valeurs pour ce registre, les résultats sont parfois amusants.
- registre BLTAFWM
Ce registre doit obligatoirement contenir la valeur $ ffff
- registre BLTALWM
Comme le précédent, ce registre doit contenir la valeur $ ffff
- registre BLTAMOD
Il doit contenir la valeur 4*PDelta-4*GDelta Vous avez bien lu : 4 et non pas 2
Même si dans un certain livre qui n’en est pas à une bêtise près (Bible de l’Amiga) c’est 2*PDelta-2*GDelta qui est indiqué alors que 4*PDelta- 4*GDelta est donné par l’AMIGA ROM KERNEL MANUAL.
Il faut bien reconnaître que la valeur donnée par la Bible semble dans ce cas convenir également, Mais une fois n’est pas coutume et l'expérience montre d’une manière générale qu’il faut toujours faire confiance aux AMIGA ROM KERNEL MANUAL et pas aux autres si vous voulez que vos programmes fonctionnent convenablement.
- registre BLIBMOD
Il doit contenir la valeur 4*PDelta.
- registre BLTCMOD
Il doit contenir la largeur du bitplane exprimée en octets. Pour un écran de 320 points de large, il faut utiliser la valeur 40.
- registre BLTDMOD
Lui aussi doit contenir la largueur du bitplane exprimée en octets.
- registre BLTAPTH
Il doit contenir la valeur 4*PDelta-2*GDelta
De plus si cette valeur est négative il faudra placer le bit à 1 le bit SIGN
du registre BLTCON1.
- registre BLTBPTH
Ce registre n’est pas utilisé pour le tracé de droite.
- registre BLTCPTH
Il doit contenir l’adresse du point de départ de la droite. Là encore, méfiez-vous de formules frelatées et utilisez celle-ci :
adresse du bitplane + yUargeur du bitplane + x1 8
à titre indicatif, la Bible de l’Amiga donne :
adresse du bitplane + (nombre de lignes - y1 -1) * nombre d'octets par ligne = 2*(x1 16)
Record battu !
Quand je vous disais qu'il valait mieux se méfier.
FI
- registre BLTCONO
Ce registre doit être
initialisé comme suit :
BIT
Nom
Fonction
15
START3
Ces 4 bits correspondent à la position du
14
START2
point de départ de la droite dans le mot
13
START1
pointé par BLTCPTH et BLTDPTH
12
START0
voir dans le programme d’exemple
11
USEA=1
Pour tracer une droite, c’est comme ça et
10
USEB=0
pas autrement
9
USEC=1
8
USED=1
7à0
Minterms
Ils doivent contenir la valeur $ CA ce qui correspond à la combinaison aC + AB (!)
- registre BLTCON1
ce registre doit être initialisé comme suit :
Bit
Nom
Fonction
15
Texture3
Mêmes valeurs que pour START3-0
14
Texture2
13 Texturel
12 TextureO
11 à 7 Ces bits sont inutilisés et doivent être placés à 0
6 SIGN Doit être mis à 1 quand 4*PDelta-2*GDelta 0
5 inutilisé : toujours 0
4 SUL Ces 3 bits doivent être initialisés avec le
3 SUD code de l’octant. Attention : décaler les bits
2 AUL de code de 2 positions à gauche.
1 SING lorsque ce bit est à 1, le Blitter trace la
droite avec seulement 1 point par ligne écran. Utile pour préparer un remplissage de surface.
0 LINE = 1 Pour activer le mode tracé de droite
- registre BLTSIZE
Ce registre doit être initialiser en dernier : c'est le signal de départ pour le Blitter.
Le contenu est donné par la formule : (GDelta+1 )*64+2
Pour comprendre la raison du 64 et du 2 reportez-vous aux articles précédents.
Certaines documentations peu sérieuses donne la formule Gdelta*64+ 2
Qu’en est-il exactement ?
Voyons un exemple x1 =100 y1 =100 x2=110 y2=110
Ceci défini une droite à 45° (le Blitter placera donc un point par “escalier”).
Comme le point x1 ,y1 fait partie de la droite, la droite comportera 11 points, il faut donc bien ajouter 1.
Autre exemple : dans un super bitplane x1 =0 y1 =0 x2=1023 y2=1023
1023 est la valeur maximum pour une coordonnée
Gdelta = 1023 - 0 = 1023 il faut donc bien ajouter 1 pour obtenir 1024 points
Il ne vous reste plus qu’à essayer le programme. Je me suis attaché à vous fournir un listing facile à comprendre. Pour cette raison il n’est pas du tout optimisé. Il est possible par exemple de remplacer les instructions muls et divs par les instructions de décalage de bits appropriées afin de gagner en rapidité si la routine doit être appelée de nombreuses fois. Il est aussi possible de passer d’autres instructions avec une programmation astucieuse. Mais je laisse tout cela à votre sagacité car je le répète mon but était de vous fournir un listing clair.
Quelques mots encore :
On a vu qu’il faut finalement beaucoup de travail pour programmer le tracé d’une pauvre petite droite. Il est peut-être plus judicieux de se contenter d’utiliser les routines de la graphies.library dans la plupart des cas. Une programmation directe du Blitter ne pouvant se justifier que pour un nombre très important de droites ou pour se faire plaisir lors de la programmtion d’une MégaDémo.
Voilà, tout est dit sur le Blitter. J’aurai le plaisir de vous retrouver le mois prochain avec un petit programme amusant sur un tout autre sujet : les lecteurs de disquettes.
F. MAZUE
Pogramme de tracé de droite à l’aide de BLUTER
* exec.library *
OldOpenLibrary
CloseLibrary
= -414 = -198 = -210 = -150 = -156
AllocMem
FreeMem
SuperState
UserState
* *' graphics.library *
OwnBlitter
- 456 ¦ 462
DisownBlitter
"* intuition.library *
CloseScreen
- 66
- 198
OpenScreen
- CHIPS*"
BLTSIZE
BLTCPTH
¦¦ $ 4C = $ 50 = $ 54
BLTBPTH
BLTAPTH
BLTDPTH
BLTCMOD
BLIBMOD
BLTAMOD
BLTDMOD
BLTCON0
BLTCON1
BLTAFWM
BLTAIWM
BLTDDAT
BLTCDAT
BLTBDAT
= $ 72
- $ 74
BLTADAT
DMACON = $ 96 DMACONR
début
move.l $ 04,a6
lea graf_name,a1 jsr 01d0penübrary(a6) move.l d0,graf_base
lea lnt_name,a1 jsr 01d0penLibrary(a6) move.l d0,int_base
move.l int_base,a6 lea écran,a0 jsr OpenScreen(ab) move.l d0,canal_ecran
bsr Blitter_Busy
move.l graf_base,a6 jsr OwnBlitter(a6)
lea $ dfi000,a5
* *** routine de traçage de droite ****
bsr recherchejxtant bsr adresse_depart
move.l d0,BLTCPTH(A5) move.l d0,BLTDFTH(A5)
move.w 40,BLTCMOD(a5) move.w 40,BLTDMOD(a5)
; nb d'octets par ligne d'écran ; nb d'oclets par ligne d'écran
clr.l d0 olr.l d1 clr.l d2 clr.l d6 clr.l d7
; mieux vaut nettoyer ces registres ; pour éviter d'éventuels ennuis avec ; le poids fort d'un long mot qui ; pourrait y subsister
move.w Pdelta,d0 move.w Gdelta.dl muls 4,d0
move.vr d0,BLIBMOD(a5) move.w d0,d2 muls 2,d1 sub.w d1 ,d0 roxl.w 7,d7
move.l d0,BLTAPTH(a5) move.w d2,d0 muls 2,d1 sub.w d1 ,d0
move.w d0,BLTAMOD(a5)
; 4*PDelta
; 2‘GDelta ; 4*PDelta-2‘GDelta ; bit sign positionne
; 4*GDelta ; 4*PDelta-4*GDelta
move.w $ 8000,BLTADAT(a5)
; un seul bit mis que le blitter ; décalera a la bonne place
move.w $ ffff,BLTBDAT(a5)
; valeur de masque
move.w $ ffff,BLTAFWM(a5) move.w $ ffff,BLTALWM(a5)
move.w X1 ,d0 and.w $ 000f,d0 ror.w 4,d0
; masque obligatoire ; les bits 0,1,2,3 deviennent ; les bits 15,14,13,12
or.w d0,d6 or.w d0,d7
; bits start0-3 positionnés ; bits texture0-3 positionnés
or.w $ 0bca,d6
; bits DMA et Minterms positionnés
move.w d6,BLTCON0(a5)
move.b octant,d0 ext.w d0 rol.w 2,d0 bset 0,d0 or.w d0,d7 ; bset 1 ,d7
; décale les bits 0,1,2 en position2,3,4 ; bit pour mode tracé de lignes
; pour tracer la droite avec un seul ; point par ligne,
; ajouter cette instruction
move.w d7,BLTCON 1 (a5)
move.w Gdelta,d0 add.w $ 01,d0 muls 64,d0 add.w 0002, d0 move.w d0,BLTSIZE(a5)
: (GDelta+1 )*64+2 ; c'est parti
bsr Blitter_Busy
jsr DisownBlitter(a6)
souris
lea $ bfe001 ,a5 btst 6,(a5) bne souris
move.l lnt_base,a6 move.l canal_ecran,a0 jsr CloseScreen(a6)
move.l $ 04, a6 move.l int_base,a1 jsr CloseLibrary(a6)
move.l graf_base,a1 jsr CloseLlbrary(a6)
rts
Blitter Busy
btst 14,DMACONR(a0) bne Blitter_Busy rts
* * recherche de l'octant "
recherche.octant
move.w X1 ,d0 move.wY1,d1 move.w X2,d2 move.w Y2,d3 move.l $ 00,d4
sub.w d1 ,d3
roxl.b 1 ,d4 ; 1er flag X passe en bit 0 dans d4 tst.w d3 ; teste le signe et si c'est négatif alors
bge y2_plus_grand_que_y1
neg.w d3 ; on inverse le signe
; car il faut DeltaY > 0
y2_plus_grand_que_y1 sub.w d0,d2
roxl.b 1 ,d4 ; 2e flag X passe en bit 0 dans d4
; 1er flag X passe en bit 1 dans d4
tst.w d2
même principe que précédemment pour DeltaX
bge x2_plus_grand_que_x1 neg.w d2
x2_plus_grand_que_x1
move.w d3,d0 sub.w d2,d0
afin de comparer les DeltaX et DeltaY
bge DeltaY_plus_grand_que_DeltaX
exg d2,d3
cette instruction ne modifie aucun flag
DeltaY_plus_grand_que_DeltaX
roxl.b 1 ,d4
dernier flag X "poussé" dans d4 d4 contient maintenant une valeur comprise entre 0 et 7 et d4 sert d'index
lea octants(pc),a0 move.b (a0,d4),d4 move.b d4,octant move.w d2,PDelta
move.w d3,GDelta rts
et voilà l'octant sélectionné
en même temps que les deltas dx et dy sont comparés et rangés
* *" calcul de l'adresse de départ de la droite ""
* "* dans le bitplane concerné **”
adresse_départ
move.w X1 ,d0 ext.l d0 divs 8,d0
and.l $ 0000ffff,d0 move.w Y1 ,d1
élimination d'un éventuel poids fort X1 est divisé par 8 éliminé le reste de la division nombre de lignes dans d1
muls 40,d1
; multiplié par nombre d'octets ; par ligned'ecran
; c'est la largeur de l’écran divisée par ; 8
add.l d1 ,d0
; le résultat de ; Y1*nbd'octets+(X1 8) test dans d0
move.l canal_ecran,a1 move.l $ c0(a1 ),d1
; adresse du bitplane dans D1
add.l
rts
d1,d0
; adresse de départ dans d0
image
dc. l 0
canal_ecran
dc. 10
int_base
dc. 10
graf_base
dc. l 0
int_name
dc. b ‘intuition.library',0
even
grai_name
dc. b 'graphics.ltbrary',0
even
écran
dc. w
dc. w
0
0
dc. w
dc. w
320
200
dc. w
dc. b
dc. b
dc. w
dc. w
2
0
1
2
15
dc. l 0
dc. l tltre_ecran
dc. l 0
dc. 10
tltre_ecran
dc. b ‘blitter demo',0
even
octant
dc,b0
even
octants
; ( en fait le code de l'octant
sur 3 bits )
dc. b 0
dc. b 4
dc. b 2
dc. b 5
dc. b 1
dc. b 6
dc. b 3
dc. b 7
; correspond à : Y1 Y2 ; correspond à : Y1 Y2 ; correspond à : Y1 Y2 ; correspond à : Y1 Y2 ; correspond à : Y1 >Y2 ; correspond à : Y1 >Y2 ; correspond à : Y1 >Y2 ; correspond à : Y1 >Y2
X1 X2 DeltaX DeltaY X1 X2 DeltaX>DeltaY X1>X2 DeltaX DeltdY X1>X2 DeltaX>DeltaY X1 X2 DeltaX DeltaY X1 X2 DeltaX>DeltaY X1>X2 DeltaX DeltaY X1>X2 DeltaX>DeltaY
X1
dc. w
0
Y1
dc. w
150
X2
dc. w
300
Y2
dc. w
100
Pdelta
dc. w 0
Gdelta
dc. w0
ÎOBEÜB
r
APPLICATION
ANIMATION de SPRITES SOUS IRQ
2» PARTIE :
ANIMER UN SPRITE: signifie modifier régulièrement sa position à l’écran d’où un déplacement visible plus ou moins rapide.
Une première considération s'impose. Pour animer un sprite, il est inutile d’effacer l’ancien, puisque les sprites sont redessinés à chaque balayage de l'écran par le faisceau d’électrons ( “raster” ).
Cette propriété distingue les sprites des “bobs" animés au blitter. Mais on peut en conclure aisément que le changement de position ne saurait se faire n'importe quand. Il est IMPERATIF de modifier la position des sprites avant le balayage de l’écran, pendant le “temps mort vertical” appelé “vertical blank”. Pour réaliser cela, on peut tester la position du faisceau d’électrons (avec les registres $ DFF004 et $ DFF006), mais le plus astucieux est d’utiliser les routines interruptions du processeur. En effet à chaque temps mort vertical, le copper envoie un signal d'interruption de niveau 3 dite IRQ3 (Interruption Request niveau 3), le microprocesseur “sautera” alors la routine correspondante. Il ne s’agit pas de supprimer cette routine, mais d’y ajouter une routine bien sentie ...
Pour cela, on respectera l'ordre suivant :
* interdire les interruptions avec move.w $ 4000,$ DFF09A ; INTENA
* mettre de côté l’adresse de la routine normale, adresse stockée en $ 6C avec move.l $ 6C,oldirq
* mettre à la place l’adresse de notre routine avec move.l newirq,$ 6C
* rétablir les interruptions avec move.l $ C000,$ DFF09A Ce qui précède implique deux choses :
1°) notre routine “newirq" doit se terminer en lançant la routine normale, ce qu’on réalise en ajoutant à la fin
dc. w $ 4EF9 ; JMP ...
oldirq: dc.l 0
2°) dans la routine newirq, il faut préserver les registres au début et les restituer à la fin avec movem.l d0-7 a0-7,-(sp)
(routine)....
movem.l (sp)+,d0-7 a0-7 comme dans l’exemple.
Pour faire un travail propre, il faut restaurer l’interruption normale quand le programme rend la main : move.w $ 4000,$ DFF09A ; supprime interruptions
move.l oldirq,$ 6C ; remet l’adresse normale
move.w $ C000,$ DFF09A ; autorise interruptions
En résumé, on peut dire que la copper-liste sert à faire les dessins (playfield ou sprites ) et que ITRQ3 sert à faire l’animation.
Une dernière précision en ce qui concerne les registres DIWSTRT et DIWSTOP qui sont fixés dans la copper-liste. La valeur de DIWSTRT conditionne celle de DDFSTRT (cycles du DMA-bitpIane) et il faut que celle-ci soit supérieure à $ 38, sinon on risque de donner au DMA-bitpIa- ne des cycles normalement alloués au DMA-sprite , ce qui empêcherait le dessin de certains sprites. En conclusion, il est préférable de fixer DIWSTRT plus grand que $ 81 en abscisse.
NEWIRQ
Que va-t-on mettre dans cette routine ? Le problème est simple : changer la position des sprites. D'après l’article sur les structures de sprites
H
(voir l’article du mois précédent), il faut pour cela changer les valeurs des mots de contrôle figurant dans les structures. Comment est déterminée la nouvelle position ?
* ou bien les sprites se déplacent suivant une ligne droite et il suffit d’ajouter ou de retrancher une certaine valeur aux coordonnées x et y
* ou bien les sprites se déplacent en suivant une courbe dont l’équation est programmée. Dans ce dernier cas, la position des sprites peut être calculée en fonction d’un paramètre variable (angle, temps, etc.) . Les calculs sont faits avec les librairies mathématiques pendant I1RQ3 : c’est le cas du programme proposé.
* ou bien on a préparé une table de valeurs qui contient les futures coordonnées et on va “pêcher”dans cette table.
Il est donc difficile de donner un modèle pour la routine "newirq” puisqu’elle dépend de la courbe choisie pour le déplacement des sprites. Dans tous les cas, on retrouvera l’ordre suivant :
* préservation des registres
* détermination des nouvelles positions
* modification des mots de contrôle dans les structures : on peut utiliser la routine “placem_sprite” du mois précédent.
* récupération des registres
* lancement de !'IRQ3 normale (comme indiqué plus haut )
Précisons tout de même certains points ...
PLACEMENTS des SPRITES
Il est nécessaire de les espacer (dans l’exemple choisi), ce qui est réalisé avec la table “Index”. Elle contient les valeurs 0,8,16,24,32. La première valeur est utilisée pour le premier sprite, la deuxième valeur est utilisée pour le deuxième sprite, etc.
La valeur 8 signifie que l'on va retrancher 8 fois le pas à l’angle courant pour calculer la position du deuxième sprite, ce qui le retarde ou l’éloigne davantage du premier (même principe pour les autres sprites). Du coup, si l’on veut rapprocher les sprites, on peut essayer 0,4,8,12,16 dans la table “index".
ATTENTION cependant : des valeurs impaires amèneront un GURU (adresse impaire) dans la routine “newirq” !
Pour éviter de recalculer à chaque interruption toutes les valeurs de cette table, toutes les valeurs sont décalées d'un cran dans la table, puis la première valeur de la table est calculée et l’angle est incrémenté. En toute logique, il faudrait alors tester si la courbe a été entièrement décrite, ce qui oblige à calculer sa période ( ici : 2 PI ). Comme dans le cas général le pas est très faible, on peut incrémenter l’angle sans test.
VITESSE de SCROLLING
En ce qui concerne la vitesse de déplacement des sprites : elle est réglable en modifiant le pas de l’angle (fixé à 0.025 radians dans l’exemple).
COURBE suivie par les SPRITES
En ce qui concerne la courbe de LISSAJOUS utilisée dans l’exemple : on peut bien sûr programmer d'autres équations dans la routine "calcul”. Signalons quelques exemples d’équations amusantes ...
* en coordonnées polaires : x = rayon * cos ( angle )
y = rayon * sin(angle) avec pour rayon r = 1 4 + cos ( 3 2 * angle )
ou r = a + cos(b * angle) en général
ou r = a * (1 + cos(angle)) cardioide
ou r = a * sin(2 * angle)
rosace à 4 branches ou r = a * cos(2 * angle)
cos(angle) de -pi 2 à pi 2
limites exclues
qui est une strophoïde droite rappel : la constante pi peut être obtenue par arc_cos(-1) avec la routine SPAcos de la mathtrans.library (voir l'article du mois précédant sur les librairies mathématiques)
* en coordonnées paramétrées : x = a * sin(m * angle)
y = b * sin(n * angle)
Ce sont les courbes de Lissajous
ou x = a * (2 cos(angle) + cos(2*angle))
y = a * (2 sin(angle) - sin(2*angle)) qui est une hypocycloïde à 3 rebroussements
ou x = a * cos3(angle)
y = a * sin3(angle) qui est une astroïde à 4 rebroussements
LES COULEURS
Il est possible de changer les couleurs des sprites en cours de scrolling.
Il suffit pour cela de modifier les couleurs fixées DANS LA COPPER- LISTE :
color 17 à 19 ; color 21 à 23 ; etc.
Cette modification doit, une fois de plus, être faite pendant l’IRQ3. Il faut repérer dans la copper-liste l’adresse du mot qui fixe la couleur en question et modifier le contenu de cette adresse. Exemple :
dc. w colorl 9,$ 00F ; coul 19 = bleu, dans la copper-liste
sera remplacé par :
dc. w colorl 9 ; coul 19
repere : ; fournit l’adresse en question
dc. w $ 00F ; = bleu
et dans la routine “newirq”, on ajoute :
move.w repere,DO ; ancienne couleur sub.w 1 ,d0 ; calcule nouvelle couleur :
$ 00E,$ 00D,$ 00C,...
; donc des bleus de nuances ; différentes move.w DO,repere ; modifie la copper-liste
Cette symphatique option permet de faire des effets de couleurs en plus du scrolling, aussi bien pour les sprites que pour le fond (color 0).
DESSINS SUPPLEMENTAIRES
En ce qui concerne enfin le bitplane qui n’est pas utilisé ici : il est possible d’ajouter un décor au dessin en transférant quelques octets dans la zone-mémoire dont l’adresse figure dans "bplanel " si l’on a ajouté dans la copper-liste :
dc. wcolorl ,$ FFF ; move.w $ FFF,$ DFF182
pour fixer la couleur 1 en blanc par exemple. Voir à ce sujet la suite d’articles sur le BUTTER et les scrollings que l’on peut en tirer.
Exemple : move.l bplanel ,a0
add.l 150*40,aO ; passe 150 lignes
move.l $ ff,d0 ; chaquebit à 1 donne 1 pixel en blanc
move.l 39,d1 ; pour remplir la ligne de 40 octets
boucle: ; en LOW-RES
move.bd0,(a0)+
dbra dO,boucle ; trace un trait horizontal à l’écran
Quelques explications au programme-source qui suit. L’ordre des opérations se réduit à ceci :
ORGANIGRAMME
* ouvertures des librairies avec test de réussite
* réservation de mémoire CHIP pour le bitplane avec test de réussite
* préparation de la copper-liste en CHIP-memory
* détournement de URQ3 : fournit la routine d’animation
* activation de la nouvelle copperliste
* lancement du DMA et attente du bouton gauche de la souris
* restauration du système : DMA, copper-liste, IRQ3
* libération de la mémoire
* fermeture des librairies
Voilà ! Vous pouvez maintenant définir vos propres sprites, les animer, bidouiller les couleurs pour faire des dégradés...
D. GENOT
ATTENTION
Ce programme nécessite la présence de la MATHTRANS.LIBRARY dans le répertoire LIBS: de votre disquette-système...
matHFFRUBRARY ********'
SPFix EQU -30
SPFlt EQU -36
SPCmp EQU -42
SPTst EQU -48
SPAbs EQU -54
SPNeg EQU -60
SPAdd EQU -66
SPSub EQU -72
SPMul EQU -78
SPDiv EQU -84
* MATHTRANS.LIBRARY *****
SPSin EQU -36
SPCos EQU -42
CUSTOM REGISTRES ******
dmaconr =02 ; lecture DMA status
intena =$ 9a ; interruptions
copllc =$ 80
copjmpl =$ 88
dmacon =$ 96 : écriture DMA status
spi0pth EQU $ 120
spr0ptl EQU $ 122
sprl pth EQU $ 124
sprlptl EQU $ 126
spr2pth EQU $ 128
spr2ptl EQU $ 12a
spr3pth EQU $ 12c
spr3ptl EQU $ 12e
spr4pth EQU $ 130
sprfptl EQU $ 132
sprôpth EQU $ 134
sprôptl EQU $ 136
sprfipth EQU $ 138
spr6ptl EQU $ 13a
spr7pth EQU $ 13c
spr7ptl EQU $ 13e
colorQ EQU $ 180
colorl EQU $ 182
colorl 7 EQU $ 1 a2
colorl 8 EQU $ 1a4
colorl 9 EQU $ 1a6
color20 EQU $ 1a8
color21 EQU $ 1 aa
color22 EQU $ 1 ac
color23 EQU $ 1 ae
color24 EQU $ 1b0
color25 EQU $ 1 b2
color26 EQU $ 1 b4
color27 EQU $ 1 b6
color28 EQU $ 1 b8
color29 EQU $ 1 ba
color30 EQU $ 1 bc
color31 EQU $ 1 be
IHÎG
* ** EXEC.UBRARY ..
move.l struct,d0
adresse datas sprites en CHIP
OldOpenLibrary =-408
move.l chiplist,a0
adresse copper-liste en CHIP
CloseLibrary =-414
add.l otf2,a0
+ offset
Forbid =-132
move.l 28*2,d1
4 mots +12 lignes de 2 mots sprite
Permit =-138
move.l 4,d2
* 5sprites
AllocMem =-198
relog3:
FreeMem =-210
move.w d0,4(a0) ; low-adresse datas sprite...
swapd0
run:
move.w d0,(a0) ; high-adresse datas sprite...
move.l gixname,a1
swapd0
moveq 0,d0
add.ld1 ,d0
adressedatas sprite suivant
move.l 4,a6
addq.l 8,a0
offset suivant dans copper-liste
jsr OldOpenLibraryfaô)
; ouvre grctphics.lib
dbrad2,relog3
place les addresses desdatas-sprites
move.l d0,_gfxbase
dans CHIP-copper-liste
beqfin ;raté
move.l 2,d2
reste3 sprites
move.l otf3,d0
offset tampon vide
move.1 ftpname,a1
addl struct,d0
moveq 0,d0
relog4:
jsr 01d0penLibrary(a6)
; ouvre mathffp.lib
move.w d0,4(a0)
low-adresse datas sprite...
move.l d0, jfpbase
swapd0
beqfin
move.w d0,(a0)
high-adresse datas sprite...
swapd0
move.l transname,a1
addq.l 8,a0
offset suivant dans copper-liste
moveq 0,d0
*
dbra d2,relog4
place les addresses des
move.l4,a6
3 datas-sprites vides
jsr 01d0penLibrary(a6)
; ouvre mathtransfiib
move.l d0,_mtbase
jsr initdatas
préparerles nombres en flottant
beqfinl
Iea$ dff000,a5
jsrForbid(a6)
move.w dmaconr a5),d0
move.w d0,dmasauv
sauve valeur actuelle DMA
move.l 40*312,d0
; 40 octets x 312 lignes
; en LOW-RES
move.w $ 4000,intena(a5)
move.l $ 10002,d1
; en CHIP avec effacement
move.l $ 6c,oldirq
jsr AllocMem(a6)
; réserve mémoire
move.l newirq,$ 6c
move.l d0,bplane1
move.w $ c000,intena(a5)
interruption IRQ3 bidouillée
beqfin2
; si impossible
move.w $ 0080,dmacon(a5)
move.l long1,d0 .
; long des datas sprites
move.l chiplist,copl IctaS)
move.l $ 10002,d1
; en CHIP avec effacement
clr.wcopjmp1(a5)
; active copperliste
jsr AllocMem(a6)
move.w $ 8380,dmacon(a5)
; c'est parti!
Move.l d0,struct
beqfin3
; si impossible
bsr souris
; nefctit rien en attendant la souris
move.l long1 ,d0
move.l _gfxbase,d0
subq.l 1,d0
move.l d0,a4
move.1 struct,a1
move.138(a4),cop1lc(a5 )
; copper-liste système
move.l im1,a0
clr.wcopjmp1(a5)
; activée
relog!:
move.w dmasauv,d0
move.b (a0)+,(a1 )+
add.w $ 8000,d0
dbrad0,relog1
; reloge en CHIP les datas sprites
move.w d0,dmacon(a5)
; DMArestauré
move.l long2,d0
; long de copper-liste
move.w $ 4000,intena(a5)
move.l $ 10002,d1
; en CHIP avec effacement
move.l oldirq,$ 6c
jsr AllocMem(a6)
move.w $ c000,intena(a5)
; interruption IRQ3 restaurée
move.l d0,chiplist
beqfin4
; si impossible
move.l _gfxbase,a1
move.l long2,d0
subq.l 1,d0
move.l 4,aê jsr CloseLibrary(a6)
; ferme graphicsiib
move.l chiplist.al
fin5:
move.l clist,a0
move.14,a6
relog2:
move.b (a0)+,(a1)+ dbrad0,relog2
; recopie en CHIP la copper-liste
move.i long2,d0 move.l chiplist,a1 jsrFreeMem(a6)
; taille mémoire ; adresse mémoire ; libère mémoire copper-liste
move.l bplane1,d0
; adresse bitplane
move.i chiplist,a0
; adresse copper-liste
fin4:
add.l off1,00
; +offset
move.14,a6
move.w d0,4(a0)
; copper liste : bitplanelow-adresse
move.1 long1 ,d0
; taille mémoire
swapd0
move.1 struct.al
; adresse mémoire
move.w d0,(a0)
; bitplane high-adresse
jsrFreeMem(a6)
; libère mémoire datas sprite
40
tin3:
move.14,aô
move.l 40’31240
; taille mémoire
move.l bplane1,a1
; adresse mémoire
jsrFreeMem(aô)
; libère mémoire bitpiane
tin2:
move.i 4,a6
jsrPermit(aô)
move.1 _mtbase,a1
move.i 4,a6
jsr CioseIibrary(aô)
; ierme-les
fini:
move.i _fipbase,a1
move.14,aô
jsr Closeubrary(a6)
; iib. Mathématiques
fin:
rts
souris:
btst 6,$ bie001
; bouton gauche enfoncé ?
Bne souris
ns
newirq:
; nouveilelRQ3
movem.l d0-7 a0-7,-(sp)
; sauve registres
move sr,-(sp)
;etFLAGS
move.l strua,a1
; adresse datas 1er sprite
iea index,a2
; index de position
move.1 4,d3
;x5sprites
boni:
move.i (a2),a2
iea tabx,a0
clr.ld0
move.w (a0,d2)40
:x
clr.l à1
iea taby,a0
move.w (a0,d2)41
;y
move.1 12,d2
: nbre lignes du sprite
jsrpiacem_sprite
; -> nouvelle position du sp
add.l 28'2,a1
; data sprite suivant
addq.i 4,a2
; index suivant
dbrad3,bani
move.l 1541
; décalede 1 mot.w
leatabx+32,a0
; toutes les positions
move.l a0,a1
; àessprites ce qui permet
addq.l 2,a1
; den'en calculer qu'une...
decal:
move.w-(a0),-(a1)
;dstabx
move.w àecaiage(a0)4ecalagê(a1 )
;àstaby
dbrad1,decal
; CALCUL nouvelle position
jsr calcul
move.w d0,tabx
; abscisse
move.w d1 ,taby
; ordonnée
move.1 angle,d0
move.i tpas,d1
; valeur d'incrémentation
move.1 _ftpbase,a6
jsrspaddlab)
; inc. angle
moved 40,angle
endirq:
move (sp)-r.sr
; récupère FLAGS
movem.1 (sp)r,d0-7 a0-7
; et registres
; IRQ3normale
CE: Al = sprite_daia ; D2 = nbre lignes D0= pos hoifx) et D1 = pos venty)
CS: mots de controie placés
; 1re ligne
; calcule dem. Ligne +1
; constantes utilisées
; origine en x et en y ;coeffx
;coetty
; param USSAIOUS
; pas = 0.025 radians ; angle courant = 0 au début
dc. w$ 4efS
oldirq:
dc. i0
piacem_spriie:
Isr.w 1 ,d0 bcssl
bcir 0,3(a1) bra suil s1:
bset 0,3(a1)
suil:
move.ba0,1(a1)
move.bd1,(a1)
bist 8,d1
bne s2
bclr 2,3(a1)
brasui2
s2:
bset 2,3(a1)
sui2:
add.ld2,d1
move.bd1,2(a1)
btst 8,d1
bnes3
bclr 1,3(a1)
bra sui3
s3:
bset 1,3(al)
sui3:
ns
initdaïas: move.l 280,d0 move.l jipbase.aô jsr spût(aô) move.ld0,xorig move.i 16040 jsrspfli(a6) move.ld0,yoiig
move.l 12040
jsrspût(a6)
move.ld0,xcoen
move.l 95,d0
jsrspit(a6)
move.l d0,ycoeti
move.l 240 jsr spût(a6) move.l d0,param1
move.l 340
jsr spflt(a6) move.ld0,param2
move.l 100040
jsrspût(a6)
move.id0,d2
move.l 2540 jsrspfitfaô) move.i d2,d1 jsrspàiv(a6) move.1 d0,tpas
clr.id0 jsr spflt(a6) move.1 d0,angle
jsr calcul
; CALCUL position de départ
; CE : aucune
lea tabx,a0
;CS:D0=xetD1=y
move.l 23,d2
ch1:
move.w d0,(a0)+
; ds tabx : même valeur pour tous
dbra d2,ch1
; les sprites
lea taby,a0
move.l 23,d2
ch2:
move.w d1 ,(a0)+
; ds taby : idem
dbra d2,ch2
rts
calcul:
; ici, on peut mettre l'équation que
move.l angle,d0
; l'on veut
move.l paraml ,d1
move.l _ffpbase,a6
jsr spmu!(a6)
move.l _mtbase,a6
jsr spsin(a6)
; sin(2t)
move.l xcoeff,d1
move.l _ffpbase,a6
jsr spmul(a6)
; ‘coeff x
move.l xorig,d1
jsr spadd(a6)
; +xorig
jsr spfix(a6)
; >x = 280 + 120 * sin (2*angle)
move.l d0,-(sp)
; mis de côté
move.l angle,d0
move.l param2,d1
jsr spmul(a6)
move.l _mtbase,a6
jsr spsin(a6)
; sin(3t)
move.l ycoeff,d1
move.l _ffpbase,a6
jsrspmul(a6)
;*coeffy
move.l yorig.dl
jsr spadd(a6)
; +yorig
jsr spfix(a6)
; >y = 160 + 95 * sin (3*angle)
move.l d0,d1
move.1 (sp)+,d0 ; CS
: D0 = x et D1 = y
rts
even
xorig: dc.l 0
yorig:dc,10
xcoeff: dc.l 0
ycoeff: dc.l 0
paraml : dc.l 0
param2: dc.l 0
fpas: dc.l 0
angle: dc.l 0
index: dc.l 0,8,16,24,32
; indique les écarts entre lessprites
even
dmasauv: dc.l 0
even
jfpbase: dc.l 0
ffpname: dc.b "mathffp.libraiy",0
even
_gfxbase: dc.l 0
glxname: dc.b "graphics,library",0
even
_mtbase: dc.l 0
transname: dc.b "mathtrans.library",0
even
clist:
; COPPER-LISTE
dc. w $ 008e,$ 2c81
;DWSTRT
dc. w $ 0090,$ 2cc1
; DWSTOP
dc. w $ 0092,$ 0038
: DDF STRT
dc. w $ 0094,$ 00d0
; DDF STOP
dc. w$ 00e0
b1 h: dc.w 0
; bitplanel high
dc. w $ 00e2
b11: dc.w 0
; bitplanel low
-
dc. w $ 0108,0000
modulo = 0
dc. w $ 0100,$ 1200
1 bitplane en LOW-RES
dc. w $ 0102,$ 0000
pas de scrolling playl.
Dc.w $ 0104,$ 0000
priorité des sprites playfield
dc. w color0,$ 000
coul. Fond
dc. w colorl 7,$ f00
couleurs sprites 0 et 1 : rouge
dc. w colorl 8,$ 0f0
vert
dc. w colorl 9,$ 00f
)leu
dc. w color21 ,$ f00
couleurs spr 2 et 3 : idem
dc. w color22,$ 0f0
dc. w color23,$ 00f
dc. w color25,$ f00
couleurs spr 4 et 5
dc. wcolor26,$ 0f0
dc. w color27,$ 00f
dc. w color29,$ f00
couleurs spr 6 et 7
dc. w color30,$ 0f0
dc. wcolor31,$ 00f
dc. w spr0pth
adresse datas sprite 0
im0h: dc.w 0
dc. w spi0ptl,0
dc. wspr1pth,0
datas spr 1
dc. wspr1ptl,0
dc. w spr2pth,0
datas spr 2
dc. wspr2ptl,0
dc. w spr3pth,0
datas spr 3
dc. wspr3ptl,0
dc. w spr4pth,0
; datas spr 4
dc. w spr4ptl,0
dc. w spr5pth,0
; datas spr 5
dc. wspr5ptl,0
dc. w spr6pth,0
; datas spr 6
dc. w spi6ptl,0
dc. w spr7pth,0
; datas spr 7
dc. w spr7ptl,0
dc. w $ ffff,$ f£fe
; fin copper-liste ( OUFFF.... ! )
fin_clist:
off1 =b1 h-clist
: offset de "b1 h" débutcopper-liste
off2=im0h-clist
; offset de "im0h" début copper-liste
even
im1: ; datas sprite 0
; VALEURSENHEXA
dc. w $ a082,$ ac00
: 12 lignes
dc. w xmmmmmmaxmmmmmm
$ 0,$ 0
dc. w %000000001111
$ F0,$ 100
dc. w %0000000i 10011 mxmtm 1000000000
$ 198,$ 200
dc. w %0000001100001100,%0000010000000000
$ 30C,$ 400
dc. w %0000000110000000,%0000001000000000
$ 180,$ 200
dc. w %0000000001100000,%0000000010000000
$ 60,$ 80
dc. w %0000000000110000,%0000000001000000
$ 30,$ 40
dc. w %0111111000011000,%1000000000100000
$ 7E18,$ 8020
dc. w %0111100000001100,%1000000000010000
$ 780C,$ 8010
dc. w %0100110000011000,%1010000000100000
$ 4C18,$ A020
dc. w %0100011000110000,%1000100001000000
$ 4630,$ 8840
dc. w %0000000111100000,%0000001000000000
$ 1E0,$ 200
dc. w %0000000000000000,%0000000000000000
$ 0,$ 0
fiml:
even
im2:
; datas sprite 1
dc. w$ a082,$ ac00
; 12 lignes
dc. w %0000000000000000,%0000000000000000
dc. w %0000000001111000,%0000000010000000
$ 78,$ 80
dc. w %0000000011001100,%0000000100010000
$ CC,$ 110
dc. w %0000000110000110,%0000001000001000
$ 186,$ 208
dc. w %0000001100000011 ,%000001
5000000100
$ 303,$ 404
dc. w %0000001100000011 ,%000001
3000000100
dc. w %0000001100000011 ,%0000010000000100
dc. w %0000001111111111 ,%000001 2
000000000
$ 3FF$ 400
dc. w %0000001100000011 ,%0000012
000000100
$ 303,$ 404
dc. w %0000001100000011 ,%0000012
000000100
dc. w %0000001100000011 ,%0000012
000000100
dc. w %0000001100000011 ,%0000012
000000100
dc. w %0000000000000000,%0000000000000000
-
even im3:
dc. w $ a082,$ ac00
dc. w °
; datas sprite 2 ; 12 lignes
dc. w %000000i mmmxmm mmmm
dc. w %0000001100000000, %0000010000000000
dc. w %0000001100000000,%0000010000000000
dc. w %0000001100000000,%0000010000000000
dc. w %00000011 00000000,%0000010000000000
dc. w %0000001100000000, %0000010000000000
dc. w %0000001100000000,%0000010000000000
dc. w
dc. w %0000001100000000,%0000010000000000
dc. w %0000001100000000,%0000010000000000
dc. w %0000001111111111 ,%0000010000000000
dc. wî
;$ 3FF,$ 400
even
im4: ; datas sprite 3
dc. w $ a082,$ ac00 ; 12 lignes
dc. w %00000000000000( de. W%0000001100000011,%0000010000000100 ;$ 303,$ 404
dc. w %0000001100000011 ,%0000010000000
dc. w %0000001100000011 ,%00000
dc. w %0000001100000011 ,%0000010000000
dc. w %0000001100000011 ,%0000010000000
dc. w %0000001100000011 ,%00000
dc. w %0000001100000011 ,%00000
dc. w %0000001100000011 ,%0000010000000
dc. w %0000000110000110,%0000001000001000
dc. w %0000000011001100,%0000000100010000
dc. w %0000000001111000,%0000000010000000
dc. w %0000000000000000,%0000000000000000
$ CC,$ 110
even
im5:
; datas sprite 4
dc. w $ a082,$ ac00
; 12 lignes
dc. w %0000000000000000,%0000000000000000
dc. w %0000111111
11111 ,%0001000000000000 ;$ FFF,$ 1000
dc. w %0000000001
00000,%0000000010000000 ;$ 60,$ 80
dc. w %0000000001
00000,%0000000010000000
dc. w %0000000001
00000,%0000000010000000
dc. w %0000000001
00000,%0000000010000000
dc. w %0000000001
00000,%0000000010000000
dc. w %0000000001
00000,%0000000010000000
dc. w %0000000001
00000,%0000000010000000
dc. w %0000000001
00000,%0000000010000000
dc. w %0000000001
00000,%0000000010000000
dc. w %0000000001
00000,%0000000010000000
dc. w %0000000000000000,%0000000000000000
even
im_vide:
; pour les autres sprites
dc. w 0,0
fin_struct:
longl =fin_struct-im1
long2=fin_clist-clist
off3=im_vide-im1
; offset de "im_vide" début datas sprite
even
tabx: ds.w 36
; absîcisses des sprites ; BLK.W 36,0avec K-SEKA
taby: ds.w 36
; ordonnées des sprites ; BLK.W 36,0
decalage=taby-tabx
; entre les 2 tables
even
bplane1:dc.l0
; adresse mémoire réservée en CHIP pour bitplane
chiplist: dc.l 0
; adresse mémoire réservée en CHIP pour copper-üste
struct: dc.l 0
; idem pour datas sprites
i r
APPLICATION
UN LECTEUR D’IMAGES IFF
LISTING
ShowIFF.s
Par Max -Mai 1990
Version Devpac II uniquement
(pour Seka, allez au diable)
Voilà qui devrait faire plaisir à un certain strasbourgeois amateur de 3D : un lec- teur décompateur d’images au format IF, toutes résolutions - sauf Overscan, faut pas exagérer.
Etant donné que je ne dispose pas de TANT pour moi tout seul (soupir), je supposerai que vous connaissez déjà les éléments principaux du format IFF pour entrer directement dans le vif du sujet. Dans le cas contraire, reportez-vous à la littérature adéquate, style “La Bible de l'Amiga” ou “Amiga Rom Kernel Reference Manual : Includes and Autodocs” pour les anglicistes.
Le programme présenté ici ne permet pas l’affichage de plusieurs images chaînées dans un seul fichier. De même, il ne prend en compte que les chunks les plus importants, à savoir : FORM (quand même !), CAMG (spécifique à l’Amiga), CMAP (palette), BFIMD (bitmap header) et BODY (les données graphiques elles-mêmes). Il accepte aussi bien les fichiers compressés (selon l’algorythme en vigueur, baptisé “ByteRunl”) que les fichiers étendus (résultats de PIFF-Converter de Deluxe Paint). Toutes les explications nécessaires sont incluses sous forme de commentaires dans le listing, aussi n’en sera-t-il pas dit plus ici. Attention, c’est parti.
-
-
inedir
"Devpac2:Include "
include
"exec execjib.i"
include
"exec memory.i"
include
"intuitiorVintuitionJib.i"
include
"intuition intuitioai"
include
"graphics graphics_lib.i"
include
"graphics view.i"
include
"graphics gfx.i"
include
"libraries dosjib.i"
include
"libraries dos.i"
; Définition de la structure BMHD façon Include rsreset
BMHDrs.b
0
bmhd_w:
rs.w1
bmhd_h:
rs.w1
FI
bmhd_x:
rs.w 1
bmhd_y:
rs.w 1
bmhd_nPlanes: rs.b
bmhd_masking: rs.b
bmhdjcompression: rs.b
bmhdjpadî : rs.b
bmhd_transparentColor: rs.w
bmhd_xAspect: rs.b
bmhd_yAspect: rs.b
bmhd_pageWidth: rs.w
bmhd_pageHeight: rs.w
0
bmhd_SEEOF: rs.w
; Définition des bits inutiles du CAMG ; en vue du masquage pour
ViewModes CAMGMASK EQU
((~(V_SPRITESIGENLOCK_VIDEO))&$ FFFF)
ExecBase EQU
4
; Petite macro pour nous simplifier la vie
CALL
MACRO
jsr
_LVO (a6)
ENDM
, _±. î .i . | ************************************
; C est parti mon kiki ! ;
Start: move.l
(ExecBase).w,a6
move.b
0,-1(a0,d0.w)
subq
1 ,d0
beq
NoArg
move.l
a0,FileName
; Ouverture de 1'intuition.library
lea
IntName(pc),a1
moveq
0,d0
CALL
OpenLibrary
move.l
d0,IntBase
beq.s
Nolnt
; Ouverture de la graphicsdibrary
lea
GfxName(pc),a1
moveq
0,d0
CALL
OpenLibrary
move.l
d0,GfxBase
beq.s
NoGfx
; Ouverture de la dosJibrary
lea
DosName(pc),a1
moveq
0,d0
CALL
OpenLibrary
move.l
d0,DosBase
beq.s
NoDos
; Charge l'image IFF
bsr.s
LoadPic
tst.l
d7
; Erreur de chargement ?
Beq.s
NoPic
; Et l'affiche
bsr
DisplayIFF
; Libère la mémoire du fichier
move.l
(ExecBase).w,a6
move.l
Picture(pc),a1
move.l
FileSize(pc),d0
CALL
FreeMem
; Ferme la dos.library NoPic :
move.l
DosBase(pc),a1
CALL
CloseLibrary
; Ferme la graphics.library NoDos :
move.l
GfxBase(pc),a1
CALL
CloseLibrary
Ferme Tintuitionlibrary NoGfx :
move.l IntBase(pc),a1
CALL CloseLibrary
Nolnt : NoArg :
rts
* Routine de chargement du fichier *
* IFF en mémoire.
* en sortie, d7 sert de flag :
* d7= 0 -> une erreur est survenue ' d7 >0 -> tout s'est bien passé
* *******************************
moveq 0,d7 ;d7=0-> erreur sinon Ok
LoadPic :
; Réserve 260 octets de CHIP-RAM pour Examineü
move.l fib_SIZEOF,d0 move.l CALL tst.l beq move.l
MEMFJ)UBLICIMEMF_CLEAR,d1
AllocMem
d0
NoMem
d0,a5
; Obtient un Lock sur le fichier
DosBase(pc),a6
FileName(pc),d1
ACCESS_READ,d2
Lock
d0,FileLock
NoLock
move.l
move.l
moveq
CALL
move.l
beq.s
; Fichier inexistant ; ExamineO le fichier
d0,d1
a5,d2
Examine
move.l
move.l
CALL
; Est-ce un répertoire ?
Fib_DirEntryType(a5)
IsDir
tst.l
bpl.s
; Oui !
Move.l fibJ3ize(a5),FileSize
; Sinon, sauve sa taille
; Réserve de la mémoire pour charger le fichier
move.l (ExecBase).w,a6
FileSize(pc),d0 MEMF_PUBLIC,d 1 AllocMem d0,Picture NoMem2
move.l
moveq
CALL
move.l
beq.s
; Ouvre le fichier
DosBase(pc),a6
FileName(pc),d1
MODE_OLDFILE,d2
Open
d0,d6
OpenErr
move.l move.l move.l CALL move.l beq
; Erreur d'ouverture
; Charge le fichier en mémoire
d0,d1
Picture(pc),d2
FileSize(pc),d3
Read
move.l
move.l
move.l
CALL
; Ferme le fichier
d6,d1 Close -1 ,d7
move.l
CALL
moveq
; d7 >0 -> Tout s'est bien passé
IsDir : NoMem2 : OpenErr :
Libère le Lock du fichier
move.l
FileLock,d1
CALL
UnLock
; Libère la mémoire d'ExamineO NoLock:
move.l
(ExecBase).w,a6
move.l
a5,a1
move.1
fibJSEEOF,d0
CALL
FreeMem
NoMem: ris
* Routine d'affichage de l'image IFF *
* Gère les modes compacté et étendu

* Alguythme de compactage :
*
' tester l'octet de contrôle n ; si n égale
; *
0. . 127 : copier n+1 octets de données '
' -1 ..-127 : répéter -n+1 fois l'octet suivant *
' -128: ne rien faire (ah bon?)
DisplayIFF:
move.l
Picture(pc),a5
;a5=imageIFF
lea
ScreenDefs(pc),a4
; a4=structure NewScreen
cmpi.l
'FORM',(a5)+
; Vérifie si c'est un fichier IFF
bne
IFFErr
; Non !
Move.l
(a5)+,d0
add.l
a5,d0
; Sauve sa taille
L-move.l
d0,FormEnd
cmpi.l
1LBM',(aS)+
; Vérifie si c'est un fichier IL3M
bne
IFFErr
Non ! . ~
; Boucle principale Do: ' move.l
(a5)+,d7
; d7=ChunkName
move.l
(a5)+,d6
; d6=ChunkSize - V
cBMHD: cmpi.l
'BMHD',d7
bne.s
cCMAP
; Chunk BMHD (Bitmap Header)
move.w
bmhd_w(a5),ns_Width(a4)
; Largeur
move.w
bmhd_h(a5),ns_Height(a4)
; Hauteur
move.b
bmhd_nPlanes(a5),ns_Dêpm-r 1 (a4)
; Profondeur
tstb
bmhd_compression(a5)
; Fichier compressé ?
Sne
Compress
; Oui -> positionne le flag
bra
Loop
; Prochain chunk
cCMAP: cmpi.l
'CMAP',d7
bne.s
cCAMG
; Chunk CMAP (Color Map)
move.w
d6,d7
ext.l
d7
divu
3,d7
; d7 = nombre de couleurs
cmpi.w
32, d7
; Plus de 32 couleurs?
Ble.s
CoulOk
moveq
32,d7
; Oui -> 32 couleurs max (c'est moi !) CoulOk :
move.w
d7,NbCoul
; Sauve le nombre de couleurs
lea
Palette(pc),a2
moveq
0,d5
subq
1 ,d7
CoLoop: move.b
(a5)+,d5
; Composante Rouge
lslw
4,d5
or.b
(a5)+,d5
; Composante Vert
lslw
4,d5
or.b
(a5)+,d5
; Composante Bleu
Isr.w
4,d5
move.w
d5,(a2)+
; Sauve le RVB dans la palette
dbra
d7,CoLoop
.¦prochaine couleur
moveq
0,d6
bra
Loop
; Prochain chunk
cCAMG : cmp.1
'CAMG',d7
bne.s
cBODY
; Chunk CAMG (Commodore Amiga)
move.l
(a5),d0
andi.l
CAMGMASK,d0
; Masque les bits indésirables
move.w
d0,ns_ViewModes(a4)
: Mode d'écran dans la structure
bra
Loop
; NewScreen (HAM, EHB, etc.)
cBODY: cmp.l
'B0DY',d7
bne
Loop
; Chunk BODY (données graphiques) STOP :
move.l
IntBase(pc),a6
; Ouvre l'écran
lea
ScreenDefs(pc),a0
move.w
USTOMSCREENlSCREENQUIET,ns_Type(a0)
CALL
OpenScreen
move.l
d0,ScrHandle
beq
IFFErr
; Si erreur, on stoppe tout ; Charge la palette de couleurs
move.l
GfxBase(pc),a6
move.1
d0,ct0
: a0 = ScreenHandle
iea
sc_ViewPort(a0),a0
Paiette(pc),a1
lea
move.w
NbCoul(pc),d0
; Nombre de couleurs
exLl
d0
CALL
LoadRGB4
; C'est parti!
; Le vrai boulot commence id
7 move.w
ns_Width(a4),d5
; Largeur en pixels
r Isr.w
3,d5
¦,18 = largeur en octets
_ -vÿ moveq : Compteur lignes Lignes : ' move.l
0,d0
ScrHandle(pc),a3
lea
x_BitMap+bm_Planes(a3),a3
move.w
ns_Depth(a4),d1
; Compteur bitplanes
7- ù" subq.w
1,d1
: -1 pour dbra Planes: move.1
(a3)+,a0
; a0 = bitplane en cours
move.w
d0,d2
⧧®Om)fe
.
Mulu
d5,d2
lea
(a0,d2.1),a0
; pointe la bonne ligne
moveq
0,d2
tst.b
Compress
; image compressée ?
Beq
Normal
; non
; Au cas où l'image est compressée Comp :
moveq
0,d3
move.b
(a5)+,d3
; octet de contrôle dans d3
bmi.s
Crunch
; négatif -> décompresser
ext.w
d3
addw
d3,d2
addq.w
1,d2
CompL:
move.b
(a5)+,(a0)+
; sinon copier n octets
dbra
d3,CompL
bra.s
NextByte
; au suivant !
Crunch:
cmpi.b
$ 80,d3
; n=-128 ($ 80) ?
Beq.s
NextByte
; oui -> rien à faire
neg.b
d3
;s on, n=-n
ext.w
d3
add.w
d3,d2
addq.w
1,d2
move.b
(a5)+,d4
; prendre octet de donnée CrunchL :
move.b
d4,(a0)+
; et le répéter n+1 fois
dbra
d3,CrunchL
;(+1 car dbra)
NextByte:
cmp.w
d5,d2
; fin de ligne atteinte ?
Blt.s
Comp
; pas encore
bra.s
NextL
si oui passe au plan suivant
Cas d'une image "étendue" (IFF-Converter) Normal : move.w d5,d4
largeur en octets
subq.w 1 ,d4
- 1 pour dbra Nloop: move.b (a5)+,(a0)+
copier les données
dbra d4,NLoop
une ligne complète
; On arrive ici quand un chunk a été traité ; (ou ignoré pour ceux qui ne sont pas gérés) Loop:
adda.l
d6,a5
; Saute le chunk
; qu'on vient de traiter
move.l
a5,d6
; Vérifie qu'a5 est pair
andib
1 ,d6
beq.s
Pair
addq.l
1 ,a5
; Si impair, on l'incrémente Pair:
A
cmpa.l
FormEnd(pc),a5
; Fin de la FORM ?
Bit
Do
; Pas encore
; Attend ALT-Gauche jVait:
*
cmpb
$ 37,$ bfec01
bne.s
Wait
; Ferme l'écran
move.l
lntBase(pc),a6
move.1
ScrHandle(pc),a0
CALL
CloseScreen
; Retour à l'envoyeur IFFErn
rts
; Variables diverses FormEnd :
dc. l
0
; Taille de la FORM Compress :
dc. b
0,0
NbCoul:
dc. w
0
; Nombre de couleurs Palette :
' ds.w
32
; Palette de 32 couleurs IntBase :
dc. l
0
GfxBase:
dc. l
0
DosBase:
dc. l
0
ScrHandle :
dc. l
0
FileName :
dc. l
0
FileLock :
dc. l
0
FileHandle :
dc. l
0
FileSize :
dc. l
0
Picture:
dc. l
0
IntName:
dcb
"intuition.library",0
even
GfxName:
dcb
"graphics.library",0
even
DosName :
dc. b
"dos.library”,0
even
; Structure NewScreen ScreenDefs: ds.b
ns_SEEOF
END
Une ligne est affichée, on passe au plan suivant NextL : dbra
d1 Planes
; Quand tous les plans de la ligne sont traités ; on passe à la ligne suivante
addq.w 1 ,d0 ; compteur de lignes incrémenté
cmp.w ns_Height(a4),d0
; la hauteur est atteinte ?
Blt.s Lignes
; non, on continue
moveq 0,d6
; si oui on a fini
Voilà, on se retrouve dans environ 30 jours avec deux routines de tri (l’une pour des nombres, l’autre pour des chaînes) demandées par
M. Sorant, gentil lecteur de... Vensuillet ? Vermuillet ? Vesrouillet (d’après notre vénéré directeur de publication, il s’agit de Vernouillet en Eure-et-Loire. La prochaine fois, écrivez mieux, tout de même...). Je vous rappelle également que si vous désirez une routine particulière, il suffit de me la demander à :
Commodore Revue Max 1 bis, rue de Paradis 75009 Paris
Bonne nuit.
Max (mais il en fait le minimum)
APPLICATION
LE MASTER MIND
Pour changer un peu de style, et pour que vous puissiez vous distraire un peu cet été, voici le jeu du master mind en GFA-Basic. Pour la petite histoire, des programmes pour ce jeu ont été créés depuis plus de quinze ans, il s’agit donc d’un classique. Le programme présenté ici peut à la fois vous faire deviner une combinaison de couleurs ou bien la chercher lui-même.
Mais ne vous attendez pas à affronter un très grand joueur. Le programme trouve généralement la combinaison au bout de 6 à 8 coups alors qu’un joueur humain ne met souvent que 5, voire 4 coups pour y arriver.
Mais, comment ça marche ? Le jeu se compose d'une grille de 11 cases sur 6, la 11e ligne étant réservée à la solution. En haut et à gauche sont affichées 8 couleurs. Le programme va commencer par vous demander si c'est vous ou lui qui doit trouver la combinaison de couleurs.
Si vous avez choisi de le laisser chercher, il vous faudra placer sur la 11e ligne la solution (ne vous inquiétez pas, il ne triche pas !). Il vous suffit de cliquer sur chaque couleur avec la souris et de la placer sur la case choisie. Le bouton de gauche sert à annuler une sélection. Vous pouvez modifier une couleur déjà sélectionnée mais une fois les 6 couleurs choisies la ligne est validée.
Ensuite, l’Amiga vous proposera une ligne de couleurs. Vous devrez alors lui indiquer les couleurs bien placées et celles qui sont présentes mais pas à la bonne position. Si vous vous trompez alors le programme deviendra fou et ne s'arrêtera plus (désolé...). Il vous restera quand même la solution d’appuyer sur Ctrl-Shift-Alt pour interrompre le programme.
Si vous avez choisi de chercher la combinaison de couleurs, vous rentrerez alors vos lignes de la même manière mais à partir de la ligne du bas en remontant d’une ligne à chaque fois. Le chiffre noir sur la droite indique le nombre de couleurs bien placées et le chiffre blanc les couleurs mal placées.
Quel que soit le joueur, il faudra trouver la solution en moins de 10 coups. A la fin, si c'est vous qui êtes le joueur, la véritable ligne s’affichera en ligne 11.
Voilà, pour tout commentaire au sujet de la programmation elle-même, je dirais que ni l’algorithme de recherche ni l’interface utilisateur ne sont réellement satisfaisants. C’est pourquoi je compte sur vous pour envoyer à Commodore Revue les améliorations que vous auriez pu y apporter. Bon divertissement.
Dominique Lorre
initvar
initgraph
ALERT 0,"Qui doit chercher ?", 1 ,"Amiga!Moi",rep%
IF rep%=1 nbcoupsl=1 saisieligne(11)
DO initligne afficheligne traiterep LOOP UNTIL nbcoupsl>10
ALERT 0,'Tai perdu !",1 ,"Domrnage...lDommage...",a%
ELSE
nbcoupsl=1
DO
saisielignelnbcoupsl) afficheresultat INC nbcoupsl LOOP UNTIL nbcoups!>10 afficheres
ALERT 0,“Vous avez perdu !",1 ,"Dommage...!Dominage...",a%
ENDIF
CLOSES 1 PROCEDURE saisierep DEFMOUSE 3 CLIP 2,115 TO 220,150 ns
CLIPOFF
fbox(2,115,220,150)
LOCATE2.15
INPUT "Couleurs placées : ",noirsl(nbcoupsl)
LOCATE2.17
INPUT “Couleurs mal placées : ",blancsl(nbcoupsl)
RETURN PROCEDURE affrep(nl,bl)
COLOR 0,2
TEXT 415,230-nbcoupsl'14,STR$ (nl)
COLOR 1,2
TEXT 430,230-nbcoupsl'14,STR$ (bl)
RETURN PROCEDURE traiterep saisierep DEFMOUSE 2
afirep(noirsl(nbcoupsl),blancsl(nbcoupsl))
1F noirsl(nbcoupsl)=nbposl
mes$ ="J'ai trouvé en "+STR$ nbcoupsl)+" coups"
ALERT 0,mes$ ,1 ,"Bravo!IBravo!",a%
CLOSES 1 END ENDIF
FORiL0TOnbposl-1
oldvisagel(il)=envisagel(il)
NEXTil
ajustecouleurs(nbcoupsl)
INC nbcoupsl DO
IF noirsl(nbcoupsl)>0 FOR il=0 TÔ noirsl(nbcoupsl)-1 envisagel(il)=oldvisagel(il)
NEXTil
ENDIF
IF blancsl(nbcoupsi)>0 FOR ibnoirsl(nbcoupsl) Tonoirsl(nbcoupsl)+blancsl(nbcoupsl)-1 REPEAT
nposl(il)=RANDOM(blancsl(nbcoupsl))+noirsl(nbcoupsl)
jl=noirsl(nbcoupsl)
correct!=NOTpacoul!(oldvisagel(nposl(il)))
IF correct!
WHILE jkil IF nposl(il)=nposl(jl) corred!=FALSE ENDIF INC jl WEND ENDIF UNTIL correct!
Envisagel(il)=oldvisagel(nposl(il))
NEXTil
ENDIF
FOR il=noirsl(nbcoupsl)+blancsl(nbcoupsl) TO nbposl-1 envisagel(il)=@getcoul(il)
NEXTil
valable!=@checkvalidite(nbcoupsl)
LOOP UNTL valable!
RETURN PROCEDURE initgraph OPENS 1,0,0,640,256,4,&H8000 color%(0L&H0 color%(1 )=&HFFF color%(2)=&HF00 color%(3)=&HF0 color%(4)=&HF color%(5)=&H808 color%(6)=&HFF0 color%(7)=&HAAA color%(8)=&H333 FORil=0TO8 SETCOLOR il,color%(il)
NEXTil SETWPEN 3,0
OPENW 1,0,0,640,256,0,&H1800 TITLEW 1 DEFMOUSE 3 fbox(255,65,405,218)
COLOR 0 FOR il=1 T04
LINE 255+il*30,65,255+il*30,218 NEXTil
FOR il=1 T014 UNE255,65+il*14,405,65+il*14 NEXTil
fbox(410,65,440,218)
PRINT CHR$ (&H9B)+"30;42m"; Ecriture Noire sur fond rouge fbox(2,70,170,90)
COLOR 0 60X 5,74,167,86 RETURN PROCEDURE Ibox(x1 ,y1 ,x2,y2)
COLOR2 PBOX x1 ,y1 ,x2,y2 COLOR1
BOX x1 -2,y1 -2,x2+2,y2+2 COLOR0
BOX x1 -1 ,y1 -i ,x2+1 ,y2+1 RETURN PROCEDURE fcircle(x,y,r,c)
COLOR8
PCIRCLEx+1,y+1,r COLORc PCIRCLE x,y,r Ifc=2 COLOR8 CIRCLE x,y,r ENDIF
RETURN PROCEDURE mitvar nbcoull=8 ! Nombre de couleurs noces!- 5 ! Nombre de positions DIM blancsl(20) ! Compte des couleurs non placées DM noirsl(20) ! Compte des couleurs placées DIM lignel(20,nbposl-1 ) ! Mémorisation des lignes DIM envrsagel(nbposl-1 ) ! Ligne envisagée DIM oldvisagel(nbposl-1 ) ! Ligne précédente envisagée DIM nposKnbposLI ) ! Tableau de position DIM jlignel(nbposi-1 ) ! Ligne du joueur DIM alignel(nbposl-1 ) ! Ligne de l'Amiga DM refcouleurKnbcoull-1 ) ! Couleurs de référence DM checkcoull(nbcoull-1 ) ! Couleurs testées DIM pacoul!(nbcoull-1 ) ! Couleurs absentes DIM color%(32) ! Valeurs des registres de couleur ' petit losange sprite$ =MKL$ (&H180)+MKL$ (&H3C0)+MKL$ (&H7E0)+MKL$ (&HFF0) sprite$ =sprite$ +MKL$ (&HFF0)+MKL$ (&H7E0)+MKL$ (&H3C0)tMKL$ (&H 180) ARRAYFILL pacoulIG.FALSE RANDOMIZE TIMER FOR i!=0 TO nbposl-1
envisagel(il)=RANDOM(nbposl)
oldvisagel(il)=envisagel(il)
alignel(il)=envisagel(il)
NEXT il
RETURN PROCEDURE iniüigne FOR il=0 TO nbposl-1
ligne I ( nbcoupsl, il )=envisage I (il )
NEXT il RETURN
PROCEDURE aflicheligne FOR il=0 TO nbposl-1
fcircle(il*30+270,225-(nbcoupsl*14),10,lignel(nbcoups!,il))
NEXT il
RETURN PROCEDURE afficheras FOR il=0 TO nbposl-1
fcircle(ir30+270,71,10,alignel(il))
NEXT il
RETURN PROCEDURE saisieligne(nl)
LOCAL il
FOR :U0 TO nbcoull-1 COLOR il
PBOX 6+il*20,75,25+020,85 NEXT il placesl=0
ARRAYFILL jlignelO, 255 DO REPEAT
MOUSE mx%,my%,mb%
UNTIL mb%=1 AND rnx%>5 AND mx% 167 AND my%>74 AND my% 86 coull=(mx%-6) D1V 20 SETCOLOR 22,color%(coull)
PAUSE 10 REPEAT
MOUSE mx%,my%,mb%
SPRITE 2,sprite$
SPRITE 2,mx%,my%
UNTIL (mb%=1 AND mx%>249 AND mx% 411 AND my%>(216-nl* 14) ANDmy% (234-nl*14» (DR mb%=2 SPRITE 2 IF mb%=1
posl=(mx%-250) DIV 30 fcircle(posl*30+270,225-(nl*14),10,coull)
IF jlignel(posl)=255 INC placesl ENDIF
jlignel(posl)=coull
ENDIF
LOOP UNTIL placestnbposl
RETURN PROCEDURE ajustecouleursfindl)
LOCAL il.nplacesl
nplacesl=noirsl(indl)+blancsl(indl )
IF nplacesbnbposl
ARRAYFILL pacoullO,TRUE FOR il=0TO nbposl-1
pacoul!(oldvisagel(il))=FALSE NEXT il ENDIF
IF nplacesl=0
FOR MOTO nbposl-1
pacoul!(oldvisage!(il))=TRUE NEXT il ENDIF
RETURN PROCEDURE afficheresultat ARRAYFILL cheokcoull(),0 ARRAYFILL refcouleurl(),0 FOR il=0TO nbposl-1 INC refcouleurl(alignel(i!))
NEXT il noirsl=0 blancsl=0
FOR il=0 TO nbposl-1 INC checkcoulKjlignel(il))
NEXT il
FOR il=0TO nbcoull-1
IF refcouleuri(il)>0 AND checkcoull(il)>0 IF checkcoull(il)>refcouleurl(il)
ADD blancsl.refcouleurl(il)
ELSE
ADD blancsl.checkcoull(il)
ENDIF
ENDIF
NEXT:!
FOR il=0 TO nbposl-1 IF (allgnel(il)=jlignel(il))
TU! Noirsl ENDIF NEXT il
blancsLblancsI-noirsl
affrepfnoirsl.blancsl)
IF noirsl=nbposl afficheras
mes$ =”Vous avez trouvé en "+STR$ (nbcoupsl)+" coups." ALERT 0,mes$ ,1 ,"Bravo!IBravo!",a%
CLOSES 1 END ENDIF
RETURN FUNCTION checkvalidite(indl)
LOCAL ni,il,jl,noirsl,blancsl ARRAYFILL refcouleurl(),0 FOR il=0 TO nbposl-1
INC refcouleurKenvisagel(il))
NEXT il
FOR nl=indl-1 DOWNTO 1 ARRAYFILL checkcoull(),0 noirsl=0 blancsl=0
FOR il=0TO nbposl-1
INC checkcoul IfligneKnl ,il ))
NEXT il
FOR il=0 TO nbcoull-1
IF refcouleurl(il)>0 AND checkcoull(il)>0 IF checkcoull(il)>refcouleurl(il)
ADD blancsl,refcouleurl(il)
ELSE
ADD blancsl,checkcoull(il)
ENDIF ENDIF NEXT il
FOR il=0 TO nbposl-1
IF (envisagel(il)=lignel(nl,il))
INC noirsl ENDIF NEXT il
blancsbblancsl-noirsl
IF NOT (noirsl=noirsl(nl) ANE' blancsl=blancsl(nl)) RETURN FALSE ENDIF NEXT n!
RETURN TRUE ENDFUNC
FUNCTION getcoul(indl)
LOCAL couleurl DO
couleurURANDOM(nbcoull)
LOOP WHLE pacoull(couleurl)
RETURN couleurl ENDFUNC
LE 3D C EN PERSPECTIVE
- TX
- Ty
- Tz
1
- sin(phi)
- sin(teta).cos(phi)
cos(teta.cos(phi)
0
0
cos(teta)
sin.(teta)
0
Soit M-1
Alors que les projections parallèles suivent les règles de la géométrie affine classique, les projections perspectives suivent leur propre géométrie. Dans une perspective deux lignes parallèles quelconques ne sont plus parallèles. La longueur d’un segment est réduite par un facteur proportionnel à sa distance par rapport à l’observateur.
Ceci implique deux choses :
- aucune information dimensionnelle ne peut être extraite d’une projection perspective,
- cette compression des distances produit un excellent effet de profondeur, très utile pour le rendu réaliste de scènes, car elle correspond à notre vision naturelle de l'espace.
En utilisant les coordonnées homogènes, la perspective peut être assimilée à une transformation classique de l’espace 3D vers l’espace 3D. Dès lors il ne reste plus qu’à réaliser une projection orthographique et la projection perspective est réalisée (simple non !!).
Lorsque la direction de vision est confondue avec un des axes principaux du repère objet, cette projection perspective est des plus simple. La figure 1 vous montre, de manière intuitive, le principe de modélisation de la perspective.
On peut s'imaginer que le pian de projection, c’est-à-dire l’écran de votre Amiga, est une vitre placée entre l’observateur et les objets. La projection perspective est alors simplement l’image des objets perçus par l’observateur à travers la vitre.
Comme on désire toujours obtenir les coordonnées de projections dans le plan de projection (écran), il est nécessaire de décrire l'ensemble des données utiles à une perspective, par rapport au plan de projection.
Une perspective simple est définie par 3 éléments :
- un centre de projection [0, 0, L, 1]
- une direction de vision [0, 0, -1, 0]
- un plan de projection Z = 0
Un point P [x y z w] se transforme en perspective en P’ jx' y’ z’w'j à l’aide de la matrice
A partir de cette matrice de projection perspective on peut calculer les coordonnées du point projeté :
x'
X
10 0 0
y'
=
y
0 10 0
z'
z
0 0 0 0
w'
w
0 0 a 0
Soit x' = x
y' = y
z' = 0
w’ = -a*z +wavec toujours a = -1 L.
On revient en coordonnées unitaires non homogène 2D pour affichage à l’écran. C'est-à-dire :
Bonjour à toutes et à tous ! Ce mois-ci nous allons terminer l’étude des différentes projections planes par les projections perspectives. Et puis, comme il me restait un peu de temps, j’ai modifié le petit programme d’affichage d’objet 3D du numéro 23 pour permettre le calcul de la perspective et l’animation temps réel de cet objet (vous verrez cela se réalise très simplement).
1
0
0
0
1
0
0
0
1
0
0
0
0
1
0
0
0
1
0
1
=
0
1
0
0
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
1
0
0
a
0
0
0
a
1
A partir de cette matrice de transformation perspective on obtient la matrice de projection perspective en multipliant cette matrice par une matrice de projection orthographique suivant z.
LES PROJECTIONS PERSPECTIVES
avec a = -1 L.
La matrice de transformation générale se calcule donc assez simplement.
Mtranspersp(phi.teta) = Mtranspersp.M-1
On peut alors déterminer la matrice de projection perspective de la même manière en remplaçant Mtranspersp par la matrice Mprojpersp. Mprojpersp(phi.teta) = Mprojpersp.M-1
- sin(phi) cos(phi) 0 -Tx
Mprojpersp(phi.teta) =-sin(teta).cos(phi) -sin(teta).sin(phi) cosffeta) -Ty 0 0 0 0
0 0 0 1
Ce qui donne en calculant P’ = P.Mprojpersp(phi.teta) :
x’ = -x.sin(phi)+y.cos(phi) -Tx.w
y’ = -x.sin(teta).cos(phi) - y.sin(teta).cos(phi)
z’ = 0
w’ = -(x.cos(teta).cos(phi)) L - (y.cos(teta).sin(phi)) L -(z.sin(teta)) L +((Tz+L).w) L
On ramène l’ensemble en coordonnées unitaires 2D non homogènes à i’aide des formules, x’’ = x' w’
y” = y’ w’ avec pour hypothèse w = 1.
A partir des données de base :
Centre de projection ‘obsv’ et Point vise ‘vise’ nous avons la direction de vision
Direction = [xobsv-xvise, yobsv-yvise, zobsv-zvise, 1]. Et sa norme vaut:
IdirectionI = sqrt((xobsv-xvise)A2+(yobsv-yvise)A2+(zobsv-zvise)A2).
La projection sur le plan z = 0 donne :
Dirproj = [xobsv-xvise,yobsv-yvise,0,1].
Ce vecteur peut être normalisé :
Idirprojl = sqrt((xobsv-xvise)A2 + (yobsv-yvise)A2)
Dès lors nous avons directement les 2 cosinus et sinus de la projection. Cos(phi) = (xobsv-xvise) IDirprojl sin(phi) = (yobsv-yvisej IDirprojl cos(teta)= Idirprojl IDirectionl sin(teta) = (zobsv-zvise) IDirectionl
Cette astuce évite le calcul des cosinus et sinus très gourmands en temps de calcul. Bien, sur ces fortes paroles je vais arrêter la théorie et passer à la pratique en vous proposant une version remaniée du petit programme d’affichage d’objet en 3D du numéro 23. En prime et sans
x" = x’ w’. Y" = y’ w’. Soit x" = x*(1 (-z L+1)) y" = y*(1 (-z L+1 ))
Ces équations correspondent à une perspective avec seul point de fuite.
Pour une direction de vision quelconque, c’est-à-dire d’une perspective générale on passe simplement le cas général au cas particulier ci-dessus en utilisant un changement de repère.
La matrice de transformation M Persp (phi.teta) est égale à la multiplication de la matrice M Persp(z) ci-dessus par une matrice de changement de repère M-1
M-1 est composée de 4 matrices :
T-1 : translation à l’observateur R-1 (z) : rotation d’axe z R-1 (y) : rotation d’axe y E-1 : échange de coordonnées M-1 se calcule de la manière suivante :
M-1 = E-1.R-1 (y).R-1 (z).T-1
cos(phi)
- sin(teta).sin(phi)
cos(teta).sin(phi)
0
57
MHI Mi
supplément j’ai modifié le programme pour qu’il y est une petite animation de l’objet. Bien sûr cette animation n’est pas parfaite mais ne désespérez pas, nous étudierons l'animation un peu plus tard.
Je vous souhaite une bonne lecture et à bientôt
Herr Doktor von GlutenStimmellmDorf est animé de bonnes intentions.
PROGRAMME DE GESTION D’OBJETS 3D AVEC DEPLACEMENT DE L’OBSERVATEUR SUIVANT UNE TRAJECTOIRE LINEAIRE. HDVGSID 1990.
Déclaration des fichiers inclus.
Tfinclude stdio.h> ttinclude math.h>
include intuition intuition.h> ffinclude intuition intuitionbase.h>
include graphics rastport.h> ttinclude graphics gfxbase.h> tfinclude graphics gfxmacros.h> tfinclude exec types.h>
Déclaration des constantes.
Ffdefine INTUrnON_REV OL ffdefine GFX.REV OL ffdefine CIAAPRA OxbfeOOl
* Adresse du Port A du CIA A
Déclaration des variables et structures globales. SHORT pointE 1 [ 100I2],pointE2( 10012]; double pointH3DÜ00I4];
SHORT * ligneE 1 [ 10012], *ligneE2[ 10012];
struct Screen ‘OpenScreenO; struct Screen 'écran = NULL ; struct IntuitionBase 'IntuitionBase = NULL; struct GfxBase 'GfxBase = NULL; struct RastPort *rp;
int nbrpoint.nbrligne; float obs[4],vise[4],matrice[4I4];
'Programme principal (ne fait pas grand chose)*
Void maint )
char 'test;
voidchargepoints(),chargelignes(),init(),ouvrecran(),referme(); void transformeO.afficheO;
test = (char *)C1AAPRA;
chargepointsO;
chargelignesO;
initO;
ouvrecranO;
1 = 0 visefl] = 0 vise[2] = 0 vise[3] = 1
* point visé par l’observateur*
obs[0] = 500;
obsll] = 500; * position de l’observateur * obs[2] = 0; obs[3] = 1;
transformetpointE 1 );
WaitTOFO;
while(!((*test & 0x40)-64)) * test du bouton gauche de la souris * I
affiched.ligneEl); obs[0] ;
obs[l] ; * trajectoire linéaire * obs[2]++;
translorme(pointE2);
WaitTOFO;
affiche®,ligneEl); * attention il n’y a pas de clipping '
affiche(l,ligneE2); * ce qui explique des effets bizarres * obslO] ; ' dans les points extrêmes *
obsll]-; obs[2]++;
transforme(pointEl);
WaitTOFO;
affiche(0,iigneE2);
refermeO;
I
'Fonction ouvrant les bibliothèques Intuition et Graphics* void initO
IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",INTUI- TIONREV);
if (IntuitionBase == NULL)
I
printfCmais ou est donc passe intuition n"); exit(FALSE);
1
GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",GFX_REV); if (GfxBase == NULL)
(
printfCmais ou est donc passe graphies n"); if (IntuitionBase) CloseLibraryûntuitionBase); exit(FALSE);
'Fonction ouvrant un simple écran et initialisant le Rastport* void ouvrecranO
struct NewScreen nouvecran;
nouvecran.LeftEdge = 0; nouvecran.TopEdge = 0; nouvecran.Width = 320; nouvecran.Height = 256; nouveCTan.Depth = 2; nouvecran.DeiailPen = 0; nouvecran.BlockPen = 0; nouvecran. ViewModes = NULL; nouvecran.Type = CUSTOMSCREEN; nouvecran.Font = NULL; nouvecran.Defaulflitle = NULL; nouveaan.Gadgets = NULL; nouvecran.CustomBitMap = NULL;
écran = OpenScreenf&nouvecran); if (écran == NULL)
I
printfCTécran ne veut pas apparaître n"); iftGfxBase) CloseLibrary(GfxBase); if (IntuitionBase) CloseLibraryOntuitionBase); exit(FALSE);
!
Rp = &(ecran->RastPort);
]
'Fonction chargeant le fichier de points 3d* void chargepointsO
I
FILE *fich,*fopen(); int i,j;
char tab(100];
fich = fopenCpoint.dat","r"); iftfich == NULL)
I
printfC'Problème d'ouverture du fichier Point.dat n"l exit(FALSE);
jpjnOEIB HBHB
fgets(tab,100,fich); nbrpoint = atoi(tab);
printfC'Chargement de la structure POINT en cours,..Ni");
for (i = 0; i nbrpoint;i++)
I
for (j = 0;j 4;j++)
(
fgetsftab, lOO.fich); pomtH3D[i][j] = atof(tab);
fclose(fich);
‘Fonction chargeant le fichier de segments* void chargelignesO
FILE *fich,*fopen(); mt : j;
char tabt 100];
fich = fopen "ligne.dat","r"); fich == NULL)
I
printfC'Problème d'ouverture du fichier ligne.datVi"); exit(FALSE);
I else I
fgetsftab, 100,fich); nbrligne = atoi(tab);
printf("Chargement de la structure LIGNE en cours... n“);
for (i = 0; i nbrligne ;i++)
I
for (j = 0; j 2 ;j++)
I
fgetsftab 100,fich);
ligneElfilj] = &pointE 1 [atoi(tab)I0];
ligneE2[i][j] = &pointE2[atoi(tab)I0]:
forfi = 0;i 3;i++) d[i] = obslil-viseli];
* calcul des cosinus, sinus et distances 7
distance = ffloat)sqrt(d[0]*d[0] + d[l]*d[l] + d[2]*d[2]);
distproj = (float)sqrt(d[0 J*d[0] + d[l]'d[l]);
costeta = distproj distance;
sinteta = d[2] distance;
cosphl = d[0] distproj;
sinphi = d[l] distproj;
* calcule de la matrice de projection perspective *
matricelOIO] = -sinphi; matrice] 1 ][0] = cosphi; matrice[2][0] = 0;
matrice[3][0] = -d[0];matrice[0][l] = -sinteta'cosphi;
matrice! 111] = -sinteta'sinphi;
matrice[2][l] = costeta;
matrice[311 ] = -d[ 1 ];
matrice[0][2] = 0;
matrice! 112] = 0;
matnce[2][2] = 0;
matrice[3][2] = 0;
matrice[0I3] = -fcosteta*cosphi) distance; matrice! 113] = -fcosteta*sinphi) distance; matrice[2][3] = -sinteta distance; matrice[3][3] = -fd[2]+distance) distance;
'Fonction affichant l'objet à l'écran* void affichefallume,ligne)
SHORT allume;
SHORT ‘ligne! 10012];
I
int i;
SetAPenfrp, allume); for(i=0;i nbrligne;i++)
fcloseffich);
'Fonction appliquant une projection perspective sur l'objet* void transformefpointE)
SHORT pointEl 10012];
int i;
float pointinter[4]; void calculeperspf);
calculeperspf);
for(i=0;i nbrpoint;l++)
1
pointinterlO] = pointH3D[i][0]*matrice[0][0]+pointH3D[iI 1 l'mafricel 1 ][0]+matrb ce[3][0];
pointinter[l]
pointH3D[l][0]*matrice[0][ 1 ]+pointH3D[i][ 1 l'matricel 1 ][ 1 ]+pointH3D[ 1][2 ]* matrice!2][- 1 ]+matrice[3][ 1 ]; pointinter[3]
pointH3D[iï0]*matrice[0][3]+polntH3D[i][l]*matrice[l][3]+pointH3D[iI2]*matrice[2][-
3]+matrice[3][0];
pointE[iI0] = (SHORT)(320*(pointlnter[0] pointinter[3]))-160; pointEÏill] = (SHORT)(256'(pointinter[l] pointinter[3]))-128;
'Fonction calculant la matrice de projection perspective* void calculeperspf)
float distance, distproj, costeta,cosphi,sinteta,slnphi; float 01-11; int i;
’* calcul du vecteur direction *
'* quelques tests pour éviter les débordements *
iffligneüIOIO] 0) ligneÜIOIO] = 0;
IffligneiilOIO] > 319 ) ligne(iï0][0] = 319; iffligneiilUO] 0) ligneüIÎIO] = 0; iffligneüIHO] >319) ligne[i][ 1 ][0] = 319; if(ligne[i][0][ 1 ] 0) ligneüIOI 1 ] = 0; ll(ligne[i][0][l] > 255) ligne[i][0][l] = 255; if(ligne[i][lll] 0) llgne[i][l][l] = 0; iffligneüllll] > 255) ligneÜUIl] = 255;
Move(rp,ligne[i][0][0],ligne[i][0][l]); Drav (rp,ligne[l][ 1 ][0],llgne[iï 111 ]);
'Fonction refermant l'écran et les bibliothèques* void referme!)
If (écran) CloseScreenfecran); if (IntuitionBase) CloseLibrary(IntultionBase); if (GfxBase) CloseLibrary(GfxBase);
1
APPLICATION
LES COMMANDES DE L’AMIGADOS
Les commandes de l'AmigaDOS sont de trois sortes, La première catégorie contient toutes les commandes de gestion de fichiers telles que Copy, Delete, Rename. Assign, Mount etc. Une deuxième catégorie renferme toutes celles qui ont un rapport"avec les fichiers scripts comme If, Endif, List LFORMAT, Echo, Skip et autres. Enfin la dernière catégorie sert à la gestion de l’environnement avec Prompt, Avait Status et j’en oublie. D’ailleurs, je ne suis pas le seul à en oublier car ce sont les commandes les moins bien comprises et documentées de l'AmigaDOS,
En fait, un utilisateur normal de l’AmigaDOS n’aura besoin que des commandes de la première catégorie. Les commandes de la deuxième catégorie seront utilisées moins souvent et dans quelques cas bien précis, Quant à celles de la troisième catégorie, elles ne seront pratiquement jamais utilisées.
Je conviens avec vous que la commande Prompt n’est pas d’un intérêt vital pour l’utilisateur et que tout le monde peut arriver à s’en sortir avec le prompt standard. Par contre, des commandes comme Avail ou Info peuvent tout bonnement vous sauver la vie. Mais dans cet article nous aurons à cœur de traiter des petits détails qui agrémentent la vie de l’utilisateur autant que des commandes à utiliser en dernier remède.
SOYONS PROMPTS
Commençons donc avec Prompt. Cette commande sert à choisir le message que le CLI ou le Shell affiche par défaut. Si vous tapez : Prompt “A>” vous ferez croire que vous êtes sous MS-DOS. Mais je reconnais que la plaisanterie est de mauvais goût. Le Prompt ressemble beaucoup a la commande Echo car on peut y introduire des séquences ANSI (encore elles ? Ben oui, on vous avait prévenu,.). Comme vous savez déjà tout sur ces commandes, je ne m’éterniserai pas et vous donnerai en exclusivité le prompt utilisé par Commodore Revue (dites- moi, c’est de la fuite de secrets industriels là :
Prompt “*E[40;33m%N.%S> *E[40;31m''
En décomposant cette commande, on pourra se rendre compte que le premier *E[40;33m permet un affichage orangé du plus bel effet pour ceux que le blanc fatigue un peu. Le %N affiche le numéro du processus CLI, le . Un point (vous l'auriez deviné sans moi), le %S le chemin déjà parcouru depuis la racine, le > fera ce qu'on attend de lui et enfin le *E[40;31m élimine les vilaines tâches oranges et rend au blanc sa pureté originelle. Quelle commande magnifique, n’est-il pas ?
Mais nous n’avons pas poussé le Prompt jusqu’au bout de ses ressources. Si le %N et le %S sont très connus, ce ne sont pas les seuls à pouvoir être utilisés par la commande Prompt.
Le %N renvoie le numéro de processus CLI. Cela est également vrai de %0, %X, %l et %U. Si on utilise %0, le numéro de processus CLI sera affiché en octal, avec %X on aura un affichage hexadécimal et les deux dernières options servent à afficher une tabulation. Essayez donc : Prompt “%X5.%N> “
Prompt “%02.%N> “
Prompt “%I3.%N> “
Prompt "%U2.%N> ”
Les tabulations simples peuvent être obtenues avec les deux caractères %T suivis d’un chiffre. Ce chiffre indique la taille minimale de la commande en caractères. Pour exprimer des nombres supérieurs à 9, il faut utiliser les chiffres A à Z. En voici une illustration :
Prompt "%N.%S%TA>"
LES AUTRES COMMANDES
Quittons rapidement la commande Prompt pour aborder un sujet beaucoup plus sérieux. Combien de fois vous êtes vous demandé si un logiciel ou un ensemble de logiciel pourraient être copiés sur une disquette ne disposant plus de beaucoup de place. Pour cela vous disposez de
deux outils : la commande Info et la commande List BLOCK. La commande Info vous permettra de déterminer la place encore disponible sur la disquette :
Info DFO:
Mounted disks:
Unit Size Used Free Full Errs Status Name
DFO: 880K 1752 6 99% 0
Read Write FIDBoot
Ensuite, nous taperons la commande suivante :
List devs: BLOCK
Directory “devs:’’ on Wednesday 30-May-90
syscon 1 rwed Future 23:50:27
jdisk.device 7 rwed Future 00:27:54
players Dir rwed 06-May-90 14:37:09
MountList.FID 1 rwed 16-Nov-89 18:58:13
serial.device 11 rw-d 16-Nov-89 18:58:26
keymaps Dir rwed 22-Nov-89 12:09:47
parallel.device 4 rw-d 16-Nov-89 18:58:18
MountList 7 rwed 10-May-90 18:21:36
ramdrivl.device 5 rw-d 26-Apr-90 11:06:22
clipboard.device 14 rw-d 16-Nov-89 18:58:10
printer.device 56 rw-d 16-Nov-89 18:58:22
narrator.device 48 rw-d 16-Nov-89 18:58:16
printers Dir rwed 22-Nov-89 12:10:54
clipboards Dir rwed 12-Nov-89 11:01:30
ramdrive.device 5 rw-d 16-Nov-89 18:58:24
DiskMaster.Config 2 rwed 16-Nov-89 14:57:10
system-configuration 1 rwed 23-Jan-90 15:13:15
13 files - 4 directories -179 blocks used
Vous voyez maintenant qu’il sera impossible de copier le fichier jdisk.device sur votre disquette mais que par contre, il sera possible d’y copier à la fois le fichier ramdrive.device et le fichier system-configuration. Ceci, parce qu'il reste 6 blocs de disponibles sur la disquette, et que les fichiers jdisk.device,ramdrive.device et system-configuration occupent respectivement 7, 5 et 1 blocs. Cela est très important car les blocs ont une taille de 512 octets, ce qui fait qu’un fichier de 1000 octets tiendra sur deux blocs et un fichier de 1100 octets sur trois.
La commande Avail sert beaucoup aux développeurs. Mais elle permet souvent de simplifier ce qui ne l’était pas au départ. On oublie souvent de l’utiliser car la barre de menu du Workbench affiche la mémoire encore disponible, et qu’il est vrai que cette information suffira le plus souvent. Examinons-la de plus près :
Type
Available
In-Use
Maximum
Largest
chip
275864
247368
523232
187280
fast
1939688
674320
2614008
1460704
total
2215552
921688
3137240
1460704
Ceci correspond à une configuration de 3Mo de mémoire, dont 512 Ko de CEIIP-RAM. Un développeur tirera une multitude d’informationsde ces 3 lignes, mais un utilisateur devrait aussi savoir ce qui s’y trouve. En résumé, la première colonne indique la taille mémoire encore disponible, la deuxième la quantité de mémoire utilisée, la troisième colonne nous dit combien le système reconnaît de mémoire et la dernière colonne intitulée Largest nous donne la taille du plus grand bloc mémoire disponible. Il nous reste à étudier les lignes.
Commençons si vous le voulez bien par la mémoire CEIIP. Celle-ci sert essentiellement au graphisme et au son. Les accès aux lecteurs de disquettes en utilisent aussi. Comme notre chère machine est multitâches, un problème se pose souvent qui est l’impossibilité d'utiliser une certaine option d’un logiciel ou même l’incapacité totale de charger une application. Avant de baisser les bras, il est utile de lancer Avail. Un écran identique au Workbench (640x256 en 4 couleurs) va prendre 40 Ko de mémoire CHIP au système. Par exemple le GFA-Basic ouvre un écran haute résolution en deux couleurs.
Avec
le GFABasic
Type
Available
In-Use
Maximum
Largest
chip
212616
310616
523232
166800
fast
16 8912
965096
2614008
1187992
total
1861528
1275712
3137240
1187992
Sans
le GFABasic
Type
Available
In-Use
Maximum
Largest
chip
233224
290008
523232
187280
fast
1867456
746552
2614008
1187488
total
2100680
1036560
3137240
1187488
En utilisant Avaii de cette manière vous saurez tout sur la façon dont le GFA-Basic utilise la mémoire, et même plus.
Tout d'abord, puisque nous avons parlé de la mémoire CHIP, la colonne Largest nous confirme que 21 Koctets sont utilisés par l’écran du GFABasic (187280-166800). Pour connaître la quantité de mémoire utilisée par le GFA-Basic, vous pouvez vous baser sur les informations données par In-IJse ou par Available. Ceci, quelque soit le type de mémoire désiré. Maintenant, me direz-vous,comment peut-on savoir que les 21 Ko de mémoire CHIP qui manquent en Largest sont bien ceux de l’écran ? C’est une bonne question (j’allais vous la poser). Et bien, dans Largest on trouve le plus grand bloc mémoire disponible. Et que peut- on trouver qui prend beaucoup de mémoire CHIP dans une application, je vous pose la question (vous alliez en faire de même) ? Et oui, c'était bien de lui que l’on parlait (donc, tout va bien).
Ces remarques sont bien entendu valables pour d’autres applications comme DeluxePaint ou tout autre programme où vous pouvez utiliser la commande Avaii pour vérifier à tout moment si vous aurez assez de place en mémoire pour charger une nouvelle image. Car, le grand avantage d’avaii est que l’utilisateur peut prévoir à quel moment une application risquera de refuser de charger une image ou même un gros fichier de textes et sera alors tentée de vous afficher un message indiquant que la mémoire est insuffisante, qu’elle ne répond pas ou n’importe quoi d’autre, voire même piquer carrément sa crise et faire appel au Guru. Heureusement il y a avaii !
Dominique LORRE
INITIATION
LA DISQUETTE BOOT
(suite et fin)
Cette série d’articles sur la disquette Boot touche à sa fin. Maintenant que nous avons passé en revue les différents outils qui servent à la création d’une telle disquette, il serait sans doute utile d’examiner des exemples précis d’utilisation d’une telle disquette.
Les disquettes Boot sont de deux sortes. La première, et la plus répandue est celle que l’on utilise avec un Amiga sans disque dur. Dans ce cas il est souvent intéressant de posséder une disquette Boot par application que l’on utilise. En second lieu on peut utiliser une disquette Boot avec un disque dur si celui-ci ne possède pas l'AutoBoot ou dans certains cas particuliers pour lesquels je n’ai pas trouvé d’application pratique.
Lorsque vous achetez un logiciel du commerce, celui-ci est souvent sur une disquette Boot. A la condition expresse que celui-ci ne soit pas muni d’une protection, il vous sera possible d’en effectuer une copie de sauvegarde que vous pourrez modifier suivant vos besoins. Le genre de modifications que vous pourrez effectuer va de l’inclusion de nouvelles commandes (comme VirusX le célèbre chasseur de Virus) dans la Startup-Sequence, à la modification de la keymap (passer en clavier français avec SetMap f ou inversement si vous possédez un clavier américain modifier la keymap avec SetMap usaO), en passant par la modification des Preferences ou simplement mettre à jour certains fichiers (si votre logiciel utilisait la arp.library version 1,2 et que vous vouliez qu'il utilise la version 1.3).
Peut-être éprouverez-vous quelques doutes sur la moralité d’une opération qui consiste à bidouiller un logiciel du commerce. Je pense sincèrement que si votre logiciel n’est pas protégé contre la copie, son éditeur acceptera totalement que vous l’adaptiez à vos besoins. Par contre, il est possible que vos modifications soient telles que le logiciel refuse de fonctionner (notamment si vous avez supprimé un fichier important) et dans ce cas vous ne pourrez vous en prendre qu’à vous-même, d’où l’importance de TOUJOURS conserver la disquette originale vierge de toute modification. Etudions maintenant les différentes manières utiles de changer une disquette Boot.
Le plus souvent vous voudrez changer la keymap. Cette opération consiste à éditer le fichier Startup-Sequence et à modifier la ligne contenant la commande SetMap. Si le logiciel est américain vous trouverez SetMap usaO, s’il est allemand SetMap d, etc. Ceci ne concerne que les disquettes commerciales d’origine étrangère ou certaines disquettes de
démonstration ou du domaine public. En général, les logiciels achetés en France contiennent toujours la ligne SetMap f. Après avoir modifié la Startup-Sequence il vous faudra insérer le fichier f dans le répertoire DEVS:keymaps qui contient toutes les définitions de clavier. Vous trouverez ce fichier sur n’importe quelle disquette Workbench. Cette manipulation vous permettra d’utiliser correctement votre clavier.
DPSLIDE, FIXHUNK, ET LES AUTRES...
Un des premiers logiciels du domaine public s’appelle DPSIide. Celui-ci sert à afficher des images IFF et a permis la création de beaucoup de démos pour l’Amiga 1000. Malheureusement, si vous mettez la main sur une de ces disquettes, et que vous possédez de la mémoire Fast, ce logiciel ne fonctionnera pas vraiment comme vous l’auriez voulu. A cela il existe une solution radicale qui est d'utiliser le programme du domaine public FixHunk pour que le logiciel se charge en mémoire CHIP et une solution plus simple mais plus coûteuse en mémoire qui consiste à charger le programme NoFastMem avant le lancement de DPSIide. Dans ce cas le plus bel effet sera obtenu en insérant la ligne suivante au début de la Startup-Sequence :
Run > NIL: SYS:System NoFastMem
avec bien entendu la commande NoFastMem placée dans le tiroir System.
La modification des Preferences ne pose pas le moindre problème, La première chose à faire est de configurer son système à partir d’une disquette Workbench avec le programme Preferences en n’oubliant pas de cliquer sur Save à la fin. Ensuite, il faut copier le fichier DEVS:system- configuration nouvellement créé sur la disquette que vous voulez modifier. Enfin, si l’imprimante joue un rôle dans votre logiciel, vous devrez vous assurer que le fichier correspondant se trouve dans le répertoire DEVS:printers et vous pourrez éventuellement supprimer tous ceux qui se rapportent à des imprimantes que vous ne possédez pas.
Une autre possibilité est la mise à jour d’un ou de plusieurs fichiers. Cela se produit quand une nouvelle version du Workbench apparaît ou quand un programme du domaine public utilisé par le logiciel est amélioré. Si il s’agit d’une nouvelle version du Workbench, alors il sera intéressant d’étudier les dates de création de fichiers se trouvant sur la disquette Workbench. C’est une chose que peu de gens savent mais Commodore utilise toujours les dates de création de fichiers. Cela signifie que quand nous sommes passés de la version 34.20 du Workbench à la version 34.28, les fichiers modifiés indiquaient une date de création plus récente que ceux qui sont restés inchangés. En voici l’illustration :
Expansion, info
894 -
rwed
13-Aug-88
18:02:32
Trashcan
Dir
rwed
13-Aug-88
18:02:34
.info
70-
rwed
13-Aug-88
18:15:51
c
Dir
rwed
17-Aug-89
15:40:22
Prefs
Dir
rwed
13-Aug-88
18:16:15
System
I
Dir -
rwed
16-Aug-89
12:18:50
Dir
rwed
16-Aug-89
12:19:07
Shell
empty
rwed
13-Aug-88
18:08:18
devs
Dir
rwed
16-Aug-89
12:19:14
s
Dir
rwed
16-Aug-89
12:20:28
Shell, info
405
rwed
13-Aug-88
18:09:36
t
Dir -
rwed
13-Aug-88
18:09:38
fonts
Dir -
rwed
13-Aug-88
18:11:03
libs
Dir -
rwed
17-Aug-89
15:40:28
Empty
Dir -
rwed
13-Aug-88
18:11:48
Utilities.info
894 -
rwed
13-Aug-88
18:11:51
Disk.info
370
rwed
13-Aug-88
18:11:55
Prefs.info
894
rwed
13-Aug-88
18:11:57
System, info
894 -
rwed
13-Aug-88
18:12:01
Empty. Info
894
rwed
13-Aug-88
18:12:05
Trashcan.info
1166
rwed
13-Aug-88
18:12:09
Utilities
Dir -
rwed
16-Aug-89
12:19:38
Expansion
Dir -
rwed
13-Aug-88
18:13:31
10 files -13 directories - 39 blocks used
Ceci est le répertoire de la disquette Workbench 34.28 (obtenu avec List DFO:). Si vous consultez les dates, vous constaterez que la plupart des fichiers ou des répertoires sont datés du 13 Août 1988. Plusieurs d'entre eux ont une date de création plus récente. On en obtiendra la liste avec la commande :
List SINCE 14-Aug-88 qui nous affichera :
Directory “DFO:” on Tuesday 22-May-90
c Dir-rwed 17-Aug-89 15:40:22
System Dir-rwed 16-Aug-89 12:18:50
I Dir-rwed 16-Aug-89 12:19:07
devs Dir-rwed 16-Aug-89 12:19:14
s Dir-rwed 16-Aug-89 12:20:28
libs Dir-rwed 17-Aug-89 15:40:28
Utilities Dir-rwed 16-Aug-89 12:19:38
7 directories - 7 blocks used
Si vous consultez la liste des modifications du Workbench 34.28 (encore appelé Workbench 1.3.2), vous constaterez que seuls les répertoires mentionnés ci-dessus ont vu leur contenu changer. Allons plus loin en examinant le répertoire C:
List DF0:c nous renverra :
Directory “DFO
:c” on Tuesday 22-May-90
Run
2568
p-rwed
13-Aug-88
18:02:35
Fault
2688
p-rwed
13-Aug-88
18:02:37
Install
2436
p-rwed
13-Aug-88
18:02:40
Stack
872
p-rwed
13-Aug-88
18:02:42
Prompt
584
p-rwed
13-Aug-88
18:02:44
Else
860
p-rwed
13-Aug-88
18:02:47
Status
1772
p-rwed
13-Aug-88
18:02:51
Ed
19564
p-rwed
13-Aug-88
18:02:56
Binddrivers
2920
- rwed
13-Aug-88
18:03:00
Search
6916
p-rwed
13-Aug-88
18:03:07
Mount
5604
p-rwed
04-May-89
10:13:06
Deiete
6124
p-rwed
13-Aug-88
18:03:11
Ask
648
p-rwed
13-Aug-88
18:03:13
Edit
18164
p-rwed
13-Aug-88
18:03:19
Avail
1964
p-rwed
13-Aug-88
18:03:23
Type
2284
p-rwed
13-Aug-88
18:03:25
AddBuffers
876
p-rwed
13-Aug-88
18:03:27
SetPatch
5088
- rwec
11-May-89
19:58:30
Path
2136
p-rwed
13-Aug-88
18:03:34
Break
956
p-rwed
13-Aug-88
18:03:37
Relabel
872
p-rwed
13-Aug-88
18:03:40
nnmn ??
IHIGHÏ g ,T j
FF
3320 -
rwed 10-Mar-89
16:25:57
Join
1056 -
p-rwed 13-Aug-88
18:03:46
EndSkip
40-
p-rwed 13-Aug-88
18:03:48
SetDate
2652
p-rwed 13-Aug-88
18:03:50
Lock
1012
p-rwed 13-Aug-88
18:03:54
Résident
2692 -
p-rwed 13-Aug-88
18:03:59
Info
2068
p-rwed 13-Aug-88
18:04:01
FileNote
692
p-rwed 13-Aug-88
18:04:03
Assign
3008
- p-rwed 13-Aug-88
18:04:07
ChangeTaskPri
1072
p-rwed 13-Aug-88
18:04:10
EndCLI
696
p-rwed 13-Aug-88
18:04:13
Rename
632
p-rwed 13-Aug-88
18:04:17
Dir
8772
p-rwed 13-Aug-88
18:04:22
NewCLI
2788
p-rwed 13-Aug-88
18:04:26
NewShell
2752
p-rwed 13-Aug-88
18:04:29
Quit
1036
p-rwed 13-Aug-88
18:04:31
Why
576
p-rwed 13-Aug-88
18:04:34
Echo
992
p-rwed 13-Aug-88
18:04:39
Lab
40
p-rwed 13-Aug-88
18:04:43
DiskChange
680
p-rwed 13-Aug-88
18:04:45
GetEnv
916
p-rwed 13-Aug-88
18:04:49
Skip
1204
p-rwed 13-Aug-88
18:04:52
DiskDoctor
7036
p-rwed 09-Mar-89
16:25:16
Failat
1028
p-rwed 13-Aug-88
18:05:00
SetEnv
836
p-rwed 13-Aug-88
18:05:02
Sort
1868
p-rwed 13-Aug-88
18:05:06
RemRAD
304
- rwed 13-Aug-88
18:05:07
Exécuté
4712
p-rwed 13-Aug-88
18:05:10
Copy
9848
p-rwed 13-Aug-88
18:05:15
Makedir
768
p-rwed 13-Aug-88
18:05:17
List
9972
p-rwed 13-Aug-88
18:05:24
CD
1756
p-rwed 13-Aug-88
18:05:28
Which
2104
p-rwed 13-Aug-88
18:05:31
Date
4208
p-rwed 13-Aug-88
18:05:35
Endlf
40
p-rwed 13-Aug-88
18:05:37
If
2536
p-rwed 13-Aug-88
18:05:41
IconX
3884
- rwed 13-Aug-88
18:05:44
LoadWB
2804
- rwed 09-Mar-89
16:24:26
Protect
1396
p-rwed 13-Aug-88
18:05:51
SetClock
4884
p-rwed 09-Mar-89
17:19:12
Wait
1424
p-rwed 13-Aug-88
18:05:58
Eval
1972
p-rwed 09-Mar-89
16:24:54
Version
2680
p-rwed 13-Aug-88
18:06:06
64 files - 489 blocks used
Ici encore, il ne sera pas facile de connaître les fichiers qui ont été modifiés, La commande suivante nous y aidera :
List DF0:c SINCE 14-Aug-88
Directory “DF0:c” on Tuesday 22-May-90
Mount 5604 p-rwed 04-May-89 10:13:06
SetPatch 5088 rwed 11 -May-89 19:58:30
FF 3320 rwed 10-Mar-89 16:25:57
DiskDoctor 7036 -p-rwed 09-Mar-89 16:25:16
LoadWB 2804 rwed 09-Mar-89 16:24:26
SetClock 4884 p-rwed 09-Mar-89 17:19:12
Eval 1972 p-rwed 09-Mar-89 16:24:54
7 files - 74 blocks used
Encore une fois, en examinant la liste des fichiers modifiés sous le Workbench 34.28, on constatera que seuls ces fichiers ont été modifiés. Pour mettre à jour le répertoire C: sur sa disquetteBoot, on emploiera les commandes suivantes :
MakeDir RAM:c
List > RAM:aze Workbenchl ,3:c SINCE 14-Aug-88 LFORMAT “Copy %S%STO RAM:c”
Exécuté RAM:aze Copy RAM:c TO MonBootic
Ceci permet de ne copier que les nouveaux fichiers sur votre disquette Boot de destination. La procédure est identique pour les autres répertoires. A bientôt.
D. Lorre
font style="font-size:x-small;font-family:Arial, sans-serif;">1424 p-rwed 13-Aug-88
18:05:58
Eval
1972
p-rwed 09-Mar-89
16:24:54
Version
2680
p-rwed 13-Aug-88
18:06:06
64 files - 489 blocks used
Ici encore, il ne sera pas facile de connaître les fichiers qui ont été modifiés, La commande suivante nous y aidera :
List DF0:c SINCE 14-Aug-88
Directory “DF0:c” on Tuesday 22-May-90
Mount 5604 p-rwed 04-May-89 10:13:06
SetPatch 5088 rwed 11 -May-89 19:58:30
FF 3320 rwed 10-Mar-89 16:25:57
DiskDoctor 7036 -p-rwed 09-Mar-89 16:25:16
LoadWB 2804 rwed 09-Mar-89 16:24:26
SetClock 4884 p-rwed 09-Mar-89 17:19:12
Eval 1972 p-rwed 09-Mar-89 16:24:54
7 files - 74 blocks used
Encore une fois, en examinant la liste des fichiers modifiés sous le Workbench 34.28, on constatera que seuls ces fichiers ont été modifiés. Pour mettre à jour le répertoire C: sur sa disquetteBoot, on emploiera les commandes suivantes :
MakeDir RAM:c
List > RAM:aze Workbenchl ,3:c SINCE 14-Aug-88 LFORMAT “Copy %S%STO RAM:c”
Exécuté RAM:aze Copy RAM:c TO MonBootic
Ceci permet de ne copier que les nouveaux fichiers sur votre disquette Boot de destination. La procédure est identique pour les autres répertoires. A bientôt.
D. Lorre

Click image to download PDF

AMIGA NEWS TECH numero 14 (07-08-1990)

Merci pour votre aide à l'agrandissement d'Amigaland.com !


Thanks for you help to extend Amigaland.com !
frdanlenfideelhuitjanoplptroruessvtr

Connexion

Pub+

63% 
8.6% 
3.2% 
2.1% 
1.9% 
1.7% 
1.2% 
1% 
0.8% 
0.7% 

Today: 7
Yesterday: 110
This Week: 537
Last Week: 863
This Month: 2382
Last Month: 3511
Total: 84596

Information cookies

Cookies are short reports that are sent and stored on the hard drive of the user's computer through your browser when it connects to a web. Cookies can be used to collect and store user data while connected to provide you the requested services and sometimes tend not to keep. Cookies can be themselves or others.

There are several types of cookies:

  • Technical cookies that facilitate user navigation and use of the various options or services offered by the web as identify the session, allow access to certain areas, facilitate orders, purchases, filling out forms, registration, security, facilitating functionalities (videos, social networks, etc..).
  • Customization cookies that allow users to access services according to their preferences (language, browser, configuration, etc..).
  • Analytical cookies which allow anonymous analysis of the behavior of web users and allow to measure user activity and develop navigation profiles in order to improve the websites.

So when you access our website, in compliance with Article 22 of Law 34/2002 of the Information Society Services, in the analytical cookies treatment, we have requested your consent to their use. All of this is to improve our services. We use Google Analytics to collect anonymous statistical information such as the number of visitors to our site. Cookies added by Google Analytics are governed by the privacy policies of Google Analytics. If you want you can disable cookies from Google Analytics.

However, please note that you can enable or disable cookies by following the instructions of your browser.

Visitors

Visite depuis
03-10-2004
Visite depuis
23-02-2014