Déplacement d'un mobile à l'écran (mode graphique) avec rebonds sur 8086

Soyez le premier à donner votre avis sur cette source.

Vue 6 354 fois - Téléchargée 416 fois

Description

Donc le but de ce programme c'est d'afficher un mobile à l'écran (ici un petit bonhomme) de le faire bouger avec rafraichissment de l'image et quand il arrive au bord de l'écran de rebondir avec la règle de réflexion type billard :
sin(i)=n*sin(r)
Il y pas mal de trucs interressants : gestion de timer, d'interruption du mode graphique et utilisation du coprocesseur. C'est une application console donc pas de super présentation mais ça a le mérite d'être amusant (à faire en tout cas)

En soi le programme ne sert pas à grand chose... ou peut-être en écran de veille.
Mais je pense que ça peut permettre d'aider des gens qui voudrait faire des trucs similaires. En plus on m'a pas mal aidé ici pour ce programme et je voudrais donc poster cette source pour remercier tout le monde et leur montrer à quoi cela a servit.

Source / Exemple :


;*******************************************************
;*    projet assembleur				*
;* Déplacement d'un mobile à l'écran			*
;* Avec gestion des rebonds sur les bords par la régle	                *
;* de réflexion : sin(i)=n*sin(r)			                *  
;*					                *	
;*		par Mister patate et sa little lady	                *
;* 2004			                                	*
;*******************************************************

	name prog
		.MODEL SMALL

;******	  utilisation coprocesseur
		.486

;******   segment de pile
		.STACK 100h

;****************************************************
;******   segment de données(db:octet-dw:16bits) ****
;****************************************************
		.DATA

couleur_cadre	db	?
couleur	db	?

x	dw	70		;coordonnées de départ
y	dw	150
v	dq	1.8		;vitesse de l'objet
teta	dq	4.2		;angle initial de la trajectoire (directement en radian)
n	dq	1.0		;coefficient d'amortissement des bords (pour les rebonds)
pos	dw	?		;stockage de la position instantanée

d_x	dw	?		;variation instantanée de position
d_y	dw	?

ctr	dw	0		;compteur fin de programme
;constantes du programme
largeur		dq	320.0	;largeur écran
PiSur2		dq	1.570796327
troisPiSur2	dq	4.712388980

controle	dw	?
masque		dw	0100000100000000b

ancienne_it     dd      ?	;sauvegarde de l'ancienne configuration d'interruption

;*****************************
;*****   segment de code *****
;*****************************
		.CODE

;**** sous-programme d'interruption ****

Inter:		mov	bx,8			;mise à 8 be BX -> flag d'interruption
		mov	al,020h			;acquitement
		out	20h,al
		iret

;**** sous programme de calcul de la nouvelle position ****
calcul :	push	bx
		push	ax		
		push	cx

		mov	bx,0
		fld	teta[bx]		;charegement de téta
		fsin
		fld	v
		fmul	ST(0),ST(1)
		fistp	d_y			;d_y = V*sin (teta)

		lea	bx,d_y
		mov	ax,[bx]
		lea	bx,y
		add	ax,[bx]
		mov	[bx],ax			;y = y + V*sin (teta)

		mov	bx,0
		fld	teta[bx]
		fcos
		fld	v
		fmul	ST(0),ST(1)
		fistp	d_x			;d_x = V*cos (teta)

		lea	bx,d_x
		mov	ax,[bx]
		lea	bx,x
		add	ax,[bx]
		mov	[bx],ax			;x = x + d_x

;calcul de position
		mov	bx,0

		ffree	ST(0)
		ffree	ST(1)

		fild	x[bx]
		fild	y[bx]
		fld	largeur[bx]
		fmul	ST(0),ST(1)		;ST(0)=320*y
		fadd	ST(0),ST(2)		;ST(0)=320*y+x

		fistp	dword ptr[pos]		;recupération de pos=y*320+x

		ffree	ST(0)
		ffree	ST(1)
		pop	cx		
		pop	bx
		pop	ax

		ret

;**** sous programme pour dessiner le bonhomme ****
smile :		push	bx
		push	ax
		
		lea	bx,pos
		mov	di,[bx]

		mov	ax,0A000h		;ecriture d'un point
		mov	es,ax
		mov	al,couleur		; choix de la couleur
		mov	es:[di],al
		
		add	di,1
		mov	es:[di],al
		add	di,1
		mov	es:[di],al
		sub	di,639
		mov	es:[di],al
		add	di,321
		mov	es:[di],al
		add	di,321
		mov	es:[di],al
		add	di,322
		mov	es:[di],al
		add	di,1
		mov	es:[di],al

		add	di,315
		mov	es:[di],al
		add	di,6
		mov	es:[di],al

		add	di,313
		mov	es:[di],al
		add	di,3
		mov	es:[di],al
		add	di,2
		mov	es:[di],al
		add	di,3
		mov	es:[di],al

		add	di,312
		mov	es:[di],al
		add	di,8
		mov	es:[di],al

		add	di,312
		mov	es:[di],al
		add	di,2
		mov	es:[di],al
		add	di,4
		mov	es:[di],al
		add	di,2
		mov	es:[di],al

		add	di,313
		mov	es:[di],al
		add	di,2
		mov	es:[di],al
		add	di,1
		mov	es:[di],al
		add	di,1
		mov	es:[di],al
		add	di,3
		mov	es:[di],al

		add	di,314
		mov	es:[di],al
		add	di,6
		mov	es:[di],al

		add	di,315
		mov	es:[di],al
		add	di,1
		mov	es:[di],al
		add	di,1
		mov	es:[di],al
		add	di,1
		mov	es:[di],al
		add	di,1
		mov	es:[di],al

		pop	bx
		pop	ax
		ret

	
;********* AFFICHAGE CADRE ROUGE *******
cadre :	
	;*** première ligne ***
		mov	couleur_cadre,5
		mov	di,0

	bendan :	mov	ax,0A000h
			mov	es,ax
			mov	al,couleur_cadre	; choix de la couleur
			mov	es:[di],al
			inc	di
			cmp	di,320
		jne	bendan

	;*** seconde ligne ***
		mov	di,63680

	ben :		mov	ax,0A000h
			mov	es,ax
			mov	al,couleur_cadre	; choix de la couleur
			mov	es:[di],al
			inc	di
			cmp	di,64000
		jne	ben

	;*** colonne de gauche ***
		mov	di,320

	mop :		mov	ax,0A000h
			mov	es,ax
			mov	al,couleur_cadre	; choix de la couleur
			mov	es:[di],al
			add	di,320
			cmp	di,63680
		jne	mop

	;*** colonne de droite ***
		mov	di,639

	mip :		mov	ax,0A000h
			mov	es,ax
			mov	al,couleur_cadre	; choix de la couleur
			mov	es:[di],al
			add	di,320
			cmp	di,63999
		jne	mip
		ret

;**** calcul du changement d'angle pendant un rebond ****

;calcul coprocesseur
calculangle:	mov	bx,0
		fsin
		fld	n[bx]
		fxch	ST(1)
		fdiv	ST(0),ST(1)		;ST(0)=sin(teta)/n
		fld	ST(0)			;copie de ST(0) dans ST(1)
		fmul	ST(0),ST(0)		;ST(0)=(sin(teta)/n)²
		fld1
		fsub	ST(0),ST(1)
		fsqrt				;ST(0)=sqrt(1-(sin(teta)/n)²)  |  ST(2)=sin(teta)/n
		fxch	ST(2)
		fld	ST(2)
		fpatan				;r=arctan(ST(1)/ST(0))
		ret

;********************************************
rebond_haut :	mov	bx,0
		fld	teta[bx]

		fcom	troisPiSur2		;comparaison pour différencier les sous-cas
		fstsw	controle		;copie du mot de contrôle du coprocesseur
		mov	ax,controle
		mov	bx,masque		;masquage pour ne conserver que les bits C0 et C3
		and	ax,bx			
		jz	cas1			;saut conditionnel

		mov	bx,0			;teta<troisPiSur2
		fld	troisPiSur2		;calcul de i à partir de teta
		fsub	ST(0),ST(1)
		ffree	ST(1)

		call	calculangle

		fld	PiSur2			;calcul de teta à partir de r
		fadd	ST(0),ST(1)
		fstp	qword ptr[teta]		;charge ST(0) dans teta

		jmp	new

cas1 :		mov	bx,0			;teta>troisPiSur2

		fld	troisPiSur2
		fxch	ST(1)
		fsub	ST(0),ST(1)
		ffree	ST(1)
	
		call	calculangle

		fld	PiSur2
		fsub	ST(0),ST(1)
		fstp	qword ptr[teta]		;charge ST(0) dans teta

		jmp	new

;********************************************
rebond_bas :	mov	bx,0
		fld	teta[bx]

		fcom	PiSur2
		fstsw	controle
		mov	ax,controle
		mov	bx,masque
		and	ax,bx
		jz	cas2

		mov	bx,0			;teta<PiSur2
		fld	PiSur2
		fsub	ST(0),ST(1)
		ffree	ST(1)

		call	calculangle

		fld	troisPiSur2
		fadd	ST(0),ST(1)

		fstp	qword ptr[teta]		;charge ST(0) dans teta

		jmp	new

cas2 :		mov	bx,0			;teta>PiSur2
		fld	PiSur2			
		fsub	ST(1),ST(0)
		fxch	ST(1)
		ffree	ST(1)

		call	calculangle

		fld	troisPiSur2
		fsub	ST(0),ST(1)
		fstp	qword ptr[teta]		;charge ST(0) dans teta

		jmp	new

;********************************************
rebond_droite :	mov	bx,0
		fld	teta[bx]

		fcom	PiSur2
		fstsw	controle
		mov	ax,controle
		mov	bx,masque
		and	ax,bx
		jz	cas3

		mov	bx,0			;teta<PiSur2

		call	calculangle

		fldpi
		fsub	ST(0),ST(1)
		fstp	qword ptr[teta]		;charge ST(0) dans teta

		jmp	new

cas3 :		mov	bx,0			;teta>PiSur2
		fldpi
		fld1
		fadd	ST(0),ST(0)
		fmul	ST(0),ST(1)
		fsub	ST(0),ST(2)
		ffree	ST(1)
		ffree	ST(2)

		call	calculangle

		fldpi
		fadd	ST(0),ST(1)
		fstp	qword ptr[teta]		;charge ST(0) dans teta

		jmp	new
		
;********************************************
rebond_gauche :	mov	bx,0
		fld	teta[bx]

		fldpi
		fcom	ST(1)
		fstsw	controle
		mov	ax,controle
		mov	bx,masque
		and	ax,bx
		jz	cas4

		mov	bx,0			;teta>Pi
		fxch	ST(1)
		fsub	ST(0),ST(1)
		ffree	ST(1)

		call	calculangle

		fldpi
		fld1
		fadd	ST(0),ST(0)
		fmul	ST(0),ST(1)
		fsub	ST(0),ST(2)
		fstp	qword ptr[teta]		;charge ST(0) dans teta

		jmp	new

cas4 :		mov	bx,0			;teta<Pi
		fsub	ST(0),ST(1)
		ffree	ST(1)

		call	calculangle

		fstp	qword ptr[teta]		;charge ST(0) dans teta

		jmp	new

;**************************************
;**** début du programme principal ****
;**************************************

DEBUT:		mov	ax,@data		;récupération de l'adresse de segment
		mov	ds,ax

;*****   initialisation du mode graphique 320*200 et 256 couleurs ****
		mov	ah,00h
		mov	al,13h			;choix du mode video 13h<=>320*200*256
		int	10h

		call	cadre

;*** configuration pour l'interruption par le timer ***

		mov	al,020h			;acquitement éventuelle inerruption précédente
		out	20h,al

		mov	bx,offset ancienne_it	;sauvegarde ancienne config
                mov	eax,gs:[8*4]
                mov	[bx],eax

		mov	ax,03ch			;configuration du TIMER 36h ou 03c h
		out	43h,ax
		mov	al,08ch			;configuration N0
		out	40h,al
		mov	al,0bah
		out	40h,al				

		mov	ax,cs			;installation du sous-programme d'interruption
		shl	eax,16
		mov	ax,offset Inter	
		mov	bx,8*4
		mov	gs:[bx],eax

		in	al,21h			;activation de IRQ0
		and	al,0feh
		out	21h,al

;mise à zéro du compteur d'interruption
		mov	bx,0

boucle	:	cmp	bx,8			;boucle d'attente d'interruption
		je	affichage	
		jmp	boucle
	
affichage  :	mov	couleur,0		;dessin en noir pour effacer le vieux bonhomme
		call	smile
		call	cadre		
		call	calcul			;calcul prochaine position
		mov	couleur,4		;dessin du nouveau bonhomme
		call	smile
		
		inc	ctr

		cmp	x,308			;tests rebond
		jae	rebond_droite
		cmp	y,2
		jbe	rebond_haut
		cmp	y,189
		jae	rebond_bas
		cmp	x,1
		jbe	rebond_gauche

new :		ffree	ST(0)			;libération des registres coprocesseurs
		ffree	ST(1)			;éventuellement utilisés pour le calcul d'un rebond
		ffree	ST(2)
		ffree	ST(3)
		ffree	ST(4)

		cmp	ctr,1000		;CONDITION DE FIN
		je	FIN
		
		mov	bx,0h			;remise à zéro de bx pour le repérage du flag d'interruption
		jmp	boucle

;**** fonction de fin de programme ****
FIN:		in	al,21h			;desactivation de IRQ0
		or	al,01h
		out	21h,al

		mov	eax,offset ancienne_it	;restauration ancienne config
		mov	gs:[8*4],eax

		mov ax,4c00h
		int 21h
		end DEBUT

Conclusion :


Pour toute remarques n'hésiter pas à m'envoyer un message par le forum. Sinon pour les gens que ça interesse j'ai une autre version avec deux mobiles.

Comme ça a intéressé les gesn j'ai mis dans le zip : le code et l'EXE des versions à 1 et 2 mobiles...

Pour répondre à la question posée : non il n'y a pas de gestion du clavier pour quitter c'est au bout d'un certein nombre de dessin que le programme termine tout seul (1000 je crois soit 40 sec.). En je ne sais pas faire l'intrruption clavier mais ça m'interresse...

Codes Sources

A voir également

Ajouter un commentaire

Commentaires

Bombela
Messages postés
225
Date d'inscription
mardi 4 mars 2003
Statut
Membre
Dernière intervention
30 juillet 2008
-
Bah mec...
Il faut commencer par de petite source, que tu dois bien commenter. Essaye d'optimiser ton code, de le rendre... artistique...

Ensuite, modifie petit à petit. Ajoute des petites briques au fur et à mesure. Avec le temps, tu deviendra plus fort, et tu passera à la pierre de taille puis au roc etc...

@+
Choumoumou
Messages postés
162
Date d'inscription
jeudi 30 septembre 2004
Statut
Membre
Dernière intervention
17 novembre 2010
-
c super ton truc °_° !!

Vous me faites déprimer avec vos sources qui marchent bien ! moi j'arrive pas à les faire marcher les mienne ! snif
----------------------------
bonne continuation,
@+
Bombela
Messages postés
225
Date d'inscription
mardi 4 mars 2003
Statut
Membre
Dernière intervention
30 juillet 2008
-
NASMW

Pour moi, c'est le meileur.

On peut tout faire avec les macros etc.

@+
cs_LordBob
Messages postés
2865
Date d'inscription
samedi 2 novembre 2002
Statut
Membre
Dernière intervention
11 mai 2009
8 -
Bombela << qu'est ce que tu utilises pour assembler?
Bombela
Messages postés
225
Date d'inscription
mardi 4 mars 2003
Statut
Membre
Dernière intervention
30 juillet 2008
-
Ben utilise les interruptions logicielle fournie par le bios et le dos !

J'ai pas le temps de t'aider...

I am sorry...

@+

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.