Obligement - L'Amiga au maximum

Samedi 31 mai 2025 - 15:15  

Translate

En De Nl Nl
Es Pt It Nl


Rubriques

Actualité (récente)
Actualité (archive)
Comparatifs
Dossiers
Entrevues
Matériel (tests)
Matériel (bidouilles)
Points de vue
En pratique
Programmation
Reportages
Quizz
Tests de jeux
Tests de logiciels
Tests de compilations
Trucs et astuces
Articles divers

Articles in English


Réseaux sociaux

Suivez-nous sur X




Liste des jeux Amiga

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z,
ALL


Trucs et astuces

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z


Glossaire

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z


Galeries

Menu des galeries

BD d'Amiga Spécial
Caricatures Dudai
Caricatures Jet d'ail
Diagrammes de Jay Miner
Images insolites
Fin de jeux (de A à E)
Fin de Jeux (de F à O)
Fin de jeux (de P à Z)
Galerie de Mike Dafunk
Logos d'Obligement
Pubs pour matériels
Systèmes d'exploitation
Trombinoscope Alchimie 7
Vidéos


Téléchargement

Documents
Jeux
Logiciels
Magazines
Divers


Liens

Associations
Jeux
Logiciels
Matériel
Magazines et médias
Pages personnelles
Réparateurs
Revendeurs
Scène démo
Sites de téléchargement
Divers


Partenaires

Annuaire Amiga

Amedia Computer

Relec


A Propos

A propos d'Obligement

A Propos


Contact

David Brunet

Courriel

 


Programmation : Assembleur - Routine de lecture de la position des manettes
(Article écrit par Stéphane Schreiber et extrait d'Amiga News Tech - septembre 1991)


Quand on s'attaque à l'écriture d'un jeu, on a toujours besoin d'une routine de lecture de la position des manettes, par exemple pour décider du mouvement à donner à un sprite et/ou à un défilement. Bien que cela ne soit pas réellement compliqué sur l'Amiga, les routines habituelles ne sont pas forcément les meilleures.

Bien que le matériel de l'Amiga l'autorise à utiliser des manettes analogiques - ou "proportionnels" - comme l'IBM PC ou l'Apple II, le type le plus courant est celui mis au point par Atari à l'époque de sa console de jeu, la VCS 2600, qui offre simplement quatre commutateurs, un par dilection possible (haut, bas, gauche, droite) et qui a été repris par de multiples constructeurs, dont Commodore (on parle d'ailleurs de "standard Atari" pour ce type de manettes, autant leur laisser au moins ça...). Sur des systèmes plus anciens, comme le C64 ou l'Amstrad CPC, il suffisait de lire un octet en mémoire ou sur un port pour savoir immédiatement dans quelle(s) direction(s) la manette était poussée.

Sur l'Amiga, pour des raisons incompréhensibles, c'est un peu plus compliqué ; les bits "haut" et "gauche" occupent deux bits d'un octet, et les "bas" et "droite", deux bits d'un autre octet d'état du ou des boutons de feu étant quant à lui encore ailleurs. Bien qu'il soit toujours possible de lire ces quatre bits avec une seule instruction (MOVEW), seul l'état des bits "gauche" et "droite" est directement exploitable : il faudra d'abord masquer par un EOR l'état des bits "haut" et 'bas" avant que ce pouvoir prendre leur valeur en compte.

De fait, lorsque que l'on commence à s'intéresser à la chose, la première routine que l'on était ressemble souvent à celle publiée dans "La Bible De L'Amiga" :

assembleur

Cette routine retourne deux valeurs, dans les registres D0 et D1, indiquant respectivement l'état horizontal et l'état vertical de la manette : -1 signifie que la manette est à gauche (resp. en haut), 0 qu'il est au centre, et 1 qu'il est à droite (resp. en bas). A charge ensuite du programme appelant, de faire ce qu'il convient de ces valeurs.

Ainsi écrite, cette routine fait ce qu'on attend d'elle, mais n'est pas réellement très efficace. En tout cas, vue sa conception, elle serait beaucoup mieux si elle allait piocher dans une table les valeurs correctes : on réduirait ainsi le nombre de tests et de branchements, ce qui ferait gagner autant d'octets et de cycles. On diminurait également le décalage à droite d'un bit et le masquage par EOR, devenus superflus.

Le problème maintenant est de savoir de quelle manière organiser nos quatre bits pour en faire un index correct pour piocher dans la table ; pour cela, rappelons qu'une lecture de JOY0DAT ou JOY1DAT donne les valeurs suivantes ('G' = gauche, 'H' = haut, 'D'= droite, 'B' = bas, et 'x' indique un bit sans intérêt) :

xxxxxxGHxxxxxxDB

Après plusieurs tests, il apparaît que la manière la plus probante est la suivante :

xxxxxxGHDBxxxxxx

...qui s'obtient très facilement par une rotation de deux bits vers la droite de l'octet inférieur. Il ne reste plus qu'à décaler le mot entier de six bits vers la droite, pour obtenir un index valable, de la forme :

xxxxxxxxxxxxGHDB

En étudiant tous les cas avec un débogueur, on trouve les valeurs possibles suivantes :

assembleur

Notre table aura donc l'allure que voici (un 'X' indique une valeur non utilisée, par exemple l'impossible combinaison HBG) :

assembleur

Cette table peut être un rien optimisée, par exemple en omettant les deux 'X' finaux de change ligne (8 octets de gagnés) et en utilisant des valeurs sur des octets plutôt que des mots (50% de gagné !). Toutefois, je préfère utiliser des mots, étant donné que dans un jeu, les coordonnées des sprites sont souvent codées sur des mots. Ainsi, dans le programme principal, je n'ai plus qu'à écrire :

assembleur

...pour que les coordonnées de mon sprite soient actualisées en fonction de la position de la manette.

Il ne nous reste donc maintenant plus qu'à écrire la version finale de notre routine de lecture des manettes. Vous remarquerez que je décale le quartet GHDB de cinq bits et non de six, comme annoncé plus haut ; c'est simplement parce que j'accède à une table de mots. Les deux instructions :

assembleur

...équivalent en fait aux trois suivantes :

assembleur

...mais sont bien entendues plus courtes et plus rapides. Dans le même ordre d'idées, je lis d'abord la valeur de d1, afin de ne pas modifier d0, qui sert toujours d'index dans l'accès à la table des valeurs en X.

Notez enfin que cette routine n'est prévue que pour le port manette 1 de l'Amiga (la configuration standard de l'utilisateur voulant que la souris soit branchée dans le port 0 et la manette dans le port 1). Pour gérer une manette branchée sur le port 0 (par exemple, dans un jeu à deux joueurs), il suffit de remplacer $dff00c (JOY1DAT) par $dff00a (JOY0DAT) le reste est strictement identique.

assembleur

Conclusion

Mine de rien, on gagne beaucoup à essayer d'améliorer des routines à priori secondaires. Dans ce cas précis, on est passé d'une routine de près de 30 lignes, à une d'à peine 10. La vitesse d'exécution s'en est trouvée considérable multipliée et on s'en sort avec la satisfaction personnelle d'avoir quasiment atteint la perfection. Ce qui est loin d'être désagréable, au niveau de l'ego.

; ************************************
; * Illustration de  la  routine  de *
; * lecture des manettes.  Lit  la   *
; * manette connectée au  GAMEPORT 1 *
; * et affiche son état.             *
; ************************************
; *  © S. Schreiber pour ANT - 1991  *
; ************************************

	incdir	"include:"
	include	"libraries/dos.i"
	include	"hardware/custom.i"

	include	"exec/exec_lib.i"
	include	"libraries/dos_lib.i"

	include	"misc/easystart.i"	; pour le Workbench startup

; ************************************
DEFSTR	MACRO
	dc.b	.2-.1	; longueur de la chaine
.1	dc.b	\1	; la chaine elle-même
	IFNC	'\2',''	; si \2 n'est pas vide...
	dc.b	\2	; alors mettre \2 aussi
	ENDC
.2	even		; alignement
	ENDM

custom	EQU	$dff000

; ************************************
Start	lea	dosname(pc),a1
	moveq	#33,d0
	CALLEXEC OpenLibrary
	move.l	d0,_DOSBase
	beq	NoDos

	move.l	#conname,d1
	move.l	#MODE_OLDFILE,d2
	CALLDOS	Open
	move.l	d0,_stdout
	beq	NoCon

; ************************************
TheLoop	moveq	#joy1dat,d0	; test de la manette 1
	bsr	Joy
	move.w	d0,d4	; sauve d0

	moveq	#0,d7	; flag : imprimer LF si <> 0

; *****	Affiche l'état de l'axe vertical
	addq.w	#1,d1	; 0 = haut, 1 = milieu, 2 = bas
	lsl.w	#2,d1
	lea	tabmsg1(pc),a0
	move.l	(a0,d1.w),d0
	beq.s	.1
	movea.l	d0,a0
	bsr	Print
	addq.w	#1,d7

; *****	Affiche l'état de l'axe horizontal
.1	addq.w	#1,d4	; 0 = gauche, 1 = milieu, 2 = droite
	lsl.w	#2,d4
	lea	tabmsg2(pc),a0
	move.l	(a0,d4.w),d0
	beq.s	.2
	movea.l	d0,a0
	bsr	Print
	addq.w	#1,d7

; *****	Au besoin, passe à la ligne
.2	tst.w	d7
	beq.s	.3
	lea	lfmsg(pc),a0
	bsr	Print

; *****	Petit delai pour être 'amiga friendly'
.3	moveq	#5,d1
	CALLDOS	Delay

; *****	Fin avec le bouton de feu de la manette
	btst	#7,$bfe001
	bne.s	TheLoop

; ************************************
Ciao	move.l	_stdout(pc),d1
	CALLDOS	Close

NoCon	movea.l	_DOSBase(pc),a1
	CALLEXEC CloseLibrary

NoDos	moveq	#0,d0
	rts

; ************************************
Joy	lea	custom,a0
	move.w	(a0,d0.w),d0
	ror.b	#2,d0
	lsr.w	#5,d0
	andi.w	#%11110,d0
	move.w	JoyTabY(pc,d0.w),d1
	move.w	JoyTabX(pc,d0.w),d0
	rts

JoyTabY	dc.w	0,1,1,0,-1,0,0,-1,-1,0,0,0,0,1,0,0
JoyTabX	dc.w	0,0,1,1,0,0,0,1,-1,0,0,0,-1,-1,0,0

; ************************************
Print	moveq	#0,d3
	move.b	(a0)+,d3
	move.l	a0,d2
	move.l	_stdout(pc),d1
	CALLDOS	Write
	rts

; ************************************
_DOSBase dc.l	0
_stdout	dc.l	0
dosname	dc.b	"dos.library",0
	even
conname	dc.b	"CON:0/11/640/200/JoyTest - par S. Schreiber",0
	even

tabmsg1	dc.l	hmsg,0,bmsg
tabmsg2	dc.l	gmsg,0,dmsg

; ************************************
gmsg	DEFSTR	<"gauche ">
dmsg	DEFSTR	<"droite ">
hmsg	DEFSTR	<"haut ">
bmsg	DEFSTR	<"bas ">
lfmsg	DEFSTR	1,$0a	; Line Feed

; ************************************
	END



[Retour en haut] / [Retour aux articles]