Obligement - L'Amiga au maximum

Vendredi 29 mars 2024 - 08:17  

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 - Le drapeau (ondulation d'un logo)
(Article écrit par Jérôme Étienne et extrait d'Amiga News Tech - mai 1992)


Comme en ce moment, je souffre d'un sérieux manque d'inspiration (l'angoisse du créateur...), j'ai choisi dans les démos que je possède le premier effet que je n'avais pas encore réalisé...

Il se trouve que ce fut un drapeau. Le seul problème qui peut se poser dans ce programme est de savoir comment faire l'effet d'ondulation. Personnellement, j'ai procédé avec des sinusoïdes, une en x et une en y, le cumule des deux donnant l'effet désiré.

Du côté purement technique, il faut faire attention au fait que le logo qui sera affiché est large de 32 points et haut de 12, soit 352 points au total. Vu que tout doit s'afficher en une VBL, il faut trouver deux ou trois astuces simples et ne pas tout programmer directement.

Dans un premier temps, la courbe est précalculée, ce qui fait gagner un maximum de temps. Pour cela, un petit programme GFA construit une table de sinus en ASCII. Cette table doit être introduite juste après l'étiquette "SIN_TAB:". Elle sera modifiée par la routine "precompute_tab". Elle ne fait que multiplier chaque valeur par la valeur de "RAY_FLAG" et la remettre au même endroit (en écrasant donc le sinus). Pour ne pas provoquer d'erreur due à la destruction de la table des sinus, je mets un drapeau nommé "precomputeflag".

Dans un second temps, l'effacement de l'écran se fait de la même manière que pour les étoiles 3D publiées précédemment : au moment d'afficher les points, je sauvegarde l'adresse de l'octet de destination dans une table. Puis avec une autre routine, je lis cette table et j'efface tous les octets qui ont été inscrits. Le tout mêlé avec un léger double tampon mémoire de tableaux pour aller avec celui des écrans, et on obtient une routine relativement efficace pour effacer les points.

Dans un troisième temps, pour tracer les points, on ruse un peu avec les plans en profitant du fait que le fond de l'écran est vide et qu'aucun des points ne se superpose. Ces deux conditions permettent d'utiliser la technique appelée officieusement "un plan par couleur" : ainsi, dans notre cas, on a besoin de deux couleurs donc on initialise deux plans de bits. Pour tracer en couleur 1, on trace dans le plan de bits 1 sans effacer dans le plan de bits 2 comme il aurait fallu le faire normalement. Cela permet de gagner du temps à l'affichage et à l'effacement.

La phrase du mois, qui est un aphorisme dosadi : "où la souffrance domine, la douleur atroce est parfois un précieux pédagogue".

* TITRE: flag
* AUTEUR: j.etienne
* SUJET: ondulation d'un logo (drapeau) en point
* ASSEMBLEUR: devpac 2.14

	incdir	'devpac:include/'
	include	'exec/exec_lib.i'
	include	'hardware/custom.i'

Custom		=	$dff000
execbase	=	4

* define for screen
BPL_X		=	320
BPL_Y		=	200
BPL_DEPTH	=	2
BPL_WIDTH	=	BPL_X/8
BPL_SIZE	=	BPL_WIDTH*BPL_Y
SCR_SIZE	=	BPL_SIZE*BPL_DEPTH

* define for flag
FLAG_WIDTH	=	32
FLAG_HEIGHT	=	12
NB_POINT	=	FLAG_WIDTH*FLAG_HEIGHT
RAY_FLAG	=	10

VSYNC:	macro
.wait_vsync\@:
	move.l	vposr(a5),d0
	and.l	#$1ff00,d0
	cmp.l	#\1*$100,d0
	bne.s	.wait_vsync\@
	endm

WAIT_BLT:	macro
	lea	CUSTOM,a5
	btst	#14,dmaconr(a5)
.LOOP_WAIT_BLT\@:
	btst	#14,dmaconr(a5)
	bne.s	.LOOP_WAIT_BLT\@
	endm

******************************************************
**************  programme principal  *****************
******************************************************

	move.l	(execbase).w,a6
	lea	Custom,a5

	CALLEXEC Forbid
	move.w	#$03e0,dmacon(a5)	* all dma off except disk

	move.w	#(BPL_DEPTH<<12)+$200,bplcon0(a5)
	clr.w	bplcon1(a5)
	clr.w	bplcon2(a5)		
	move.w	#BPL_WIDTH*(BPL_DEPTH-1),bpl1mod(a5)
	move.w	#BPL_WIDTH*(BPL_DEPTH-1),bpl2mod(a5)
	move.w	#$2981,diwstrt(a5)	*\ 
	move.w	#$f1c1,diwstop(a5)	* > init un ecran 320*256
	move.w	#$0038,ddfstrt(a5)	* >
	move.w	#$00d0,ddfstop(a5)	*/ 
	bsr	BUILD_COPLIST		
	move.l	COPLIST_ADR(pc),cop1lc(a5) * > run my coplist
	clr.w	copjmp1(a5)		*/
	
	move.w	#$83C0,dmacon(a5)	* dma blitter,copper & bitplane on

	* init the cmap
	move.w	#$000,color+0*2(a5)
	move.w	#$0FF,color+1*2(a5)
	move.w	#$F00,color+2*2(a5)
	move.w	#$0F0,color+3*2(a5)

	bsr	PRECOMPUTE_TAB
	
MAIN_LOOP:
	VSYNC	$f
	bsr	BUILD_COPLIST		
	* double buffering for tab
	move.l	LOG_TAB_ADR_PT,d0
	move.l	PHY_TAB_ADR_PT,LOG_TAB_ADR_PT
	move.l	d0,PHY_TAB_ADR_PT
	* double buffering for screen
	move.l	LOG_SCR_ADR,d0
	move.l	PHY_SCR_ADR,LOG_SCR_ADR
	move.l	d0,PHY_SCR_ADR
		
	bsr	CLR_SCR
	bsr	DRAW_FLAG	
		

	btst	#6,$bfe001
	bne	MAIN_LOOP
	bra	INIT_END

CLR_SCR: *******************************************************
* this routine clears all the old points which were on this screen

	move.l	LOG_TAB_ADR_PT(pc),a0
	tst.l	(a0)			*\ dont clear the page before
	beq.s	.END_CLEAR		*/ the first stars
	move.l	#NB_POINT-1,d0
	moveq	#0,d1

.LOOP_CLEAR:
	move.l	(a0)+,a1
	move.b	d1,(a1)
	dbf	d0,.LOOP_CLEAR

.END_CLEAR
	rts 
**************************************************** END_CLEAR_SCR

PRECOMPUTE_TAB: ***********************************************
	tst.w	PRECOMPUTE_FLAG
	bne.s	.END
	move.w	#-1,PRECOMPUTE_FLAG

	lea	SIN_TAB(pc),a0
	move.w	#$200-1,d0	
.LOOP
	move.w	(a0),d1
	muls	#RAY_FLAG,d1
	add.l	d1,d1
	swap	d1
	move.w	d1,(a0)+

	dbf	d0,.LOOP
.END
	rts
PRECOMPUTE_FLAG:	dc.w	0
******************************************** END_PRECOMPUTE_TAB

DRAW_FLAG: ***********************************************************
	lea	FLAG_PICTURE(pc),a1
	move.l	LOG_TAB_ADR_PT(pc),a2

	move.l	ADR_Y(pc),a3
	add.l	SPD1_Y(pc),a3
	cmp.l	#SIN_TAB+$200*2,a3
	blt.s	.ADR_Y_LT_SIN_TAB
	sub.l	#$200*2,a3
.ADR_Y_LT_SIN_TAB
	move.l	a3,ADR_Y

	move.l	ADR_X(pc),a4
	add.l	SPD1_X(pc),a4
	cmp.l	#SIN_TAB+$200*2,a4
	blt.s	.ADR_X_LT_SIN_TAB
	sub.l	#$200*2,a4
.ADR_X_LT_SIN_TAB
	move.l	a4,ADR_X




	move.l	ADR_X(pc),a4

	move.w	OY(pc),d6
	move.w	#FLAG_HEIGHT-1,d4
.LOOP_EACH_LINE
	move.l	ADR_Y(pc),a3
	move.w	OX(pc),d5
	moveq	#FLAG_WIDTH-1,d3
.LOOP_EACH_POINT

	move.w	d5,d0
	add.w	(a4),d0
	move.w	d6,d1
	add.w	(a3),d1
	move.b	(a1)+,d2
	bsr	POINT


	add.w	DX(pc),d5

	add.l	SPD2_Y(pc),a3
	cmp.l	#SIN_TAB+$200*2,a3
	blt.s	.A3_LT_SIN_TAB
	sub.l	#$200*2,a3
.A3_LT_SIN_TAB


	dbf	d3,.LOOP_EACH_POINT
	add.l	SPD2_X(pc),a4
	cmp.l	#SIN_TAB+$200*2,a4
	blt.s	.A4_LT_SIN_TAB
	sub.l	#$200*2,a4
.A4_LT_SIN_TAB
	
	add.w	DY(pc),d6
	dbf	d4,.LOOP_EACH_LINE
	


	rts

* toutes les vitesses doivent etre indiquees en chiffre paire
ADR_X:	dc.l	SIN_TAB
SPD1_X:	dc.l	20	
SPD2_X:	dc.l	40

ADR_Y:	dc.l	SIN_TAB
SPD1_Y:	dc.l	20
SPD2_Y:	dc.l	50


DX:	dc.w	8
DY:	dc.w	12

OX:	dc.w	30
OY:	dc.w	30
******************************************************** END_DRAW_FLAG

POINT: **************************************************************
* in: d0.w = x
*     d1.w = y
*     d2.b = color 	
* out: none
* detroyed: d0/d1/a0

	move.l	LOG_SCR_ADR(pc),a0
	lsl.l	#2,d1
	add.l	ADR_LINE_ACCORDING_TO_Y(pc,d1.w),a0
	move.w	d0,d1
	lsr.w	#3,d1
	lea	(a0,d1.w),a0
	and.w	#%111,d0
	neg.w	d0
	addq.w	#7,d0
	cmp.b	#1,d2
	beq.s	.OTHER_COLOR
	move.l	a0,(a2)+
	bset	d0,(a0)
	rts
.OTHER_COLOR
	lea	BPL_WIDTH(a0),a0
	move.l	a0,(a2)+
	bset	d0,(a0)
	rts
********************************************************** END_POINT

ADR_LINE_ACCORDING_TO_Y:
DUMMY	set	0
	rept	BPL_Y
	dc.l	DUMMY
DUMMY	set	DUMMY+BPL_WIDTH*BPL_DEPTH
	endr

INIT_END: *********************************************************
* reactivation de l'ancienne coplist
	lea	GfxName(pc),a1		* nom de la library ds a1
	moveq	#0,d0			* version 0 (the last)
	CALLEXEC OpenLibrary		* lib graphique ouverte
	move.l	d0,a4			* adr de graphicbase ds a4
	move.l	38(a4),cop1lc(a5)	* chargement de l'adr de
	clr.w	copjmp1(a5)		* l'old coplist et lancement

	move.w	#$83e0,dmacon(a5)	* activation des canaux dma necessaires
	CALLEXEC Permit			* multi switching autorise

* et on retourne d'ou l'on vient.
	moveq	#0,d0	* flag d'erreur desactive
	rts

GfxName:		dc.b	"graphics.library",0
	EVEN
******************************************************* end_INIT_END

BUILD_COPLIST: ********************************************************
	move.l	COPLIST_ADR,a0
	move.l	PHY_SCR_ADR,d2
	moveq	#BPL_DEPTH-1,d0
	move.w	#bplpt,d1

.LOOP_INIT_BPL_IN_CLIST
	move.w	d1,(a0)+
	addq.l	#2,d1
	swap	d2
	move.w	d2,(a0)+
	swap	d2
	move.w	d1,(a0)+
	addq.l	#2,d1
	move.w	d2,(a0)+
	add.l	#BPL_WIDTH,d2
	dbf	d0,.LOOP_INIT_BPL_IN_CLIST
	
	move.l	#$fffffffe,(a0)+	* montre la fin de la clist
	rts
********************************************************* END_BUILD_COPLIST



FLAG_PICTURE:
	dc.b 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
	dc.b 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
	dc.b 1,1,1,1,2,2,2,2,1,1,1,1,2,2,1,1,1,1,2,2,1,1,2,2,2,2,2,2,2,2,1,1
	dc.b 1,1,1,2,2,2,2,2,2,1,1,1,2,2,2,1,1,1,2,2,1,1,2,2,2,2,2,2,2,2,1,1
	dc.b 1,1,2,2,1,1,1,1,2,2,1,1,2,2,2,2,1,1,2,2,1,1,1,1,1,2,2,1,1,1,1,1
	dc.b 1,1,2,2,1,1,1,1,2,2,1,1,2,2,1,2,2,1,2,2,1,1,1,1,1,2,2,1,1,1,1,1
	dc.b 1,1,2,2,2,2,2,2,2,2,1,1,2,2,1,1,2,2,2,2,1,1,1,1,1,2,2,1,1,1,1,1
	dc.b 1,1,2,2,2,2,2,2,2,2,1,1,2,2,1,1,1,2,2,2,1,1,1,1,1,2,2,1,1,1,1,1
	dc.b 1,1,2,2,1,1,1,1,2,2,1,1,2,2,1,1,1,1,2,2,1,1,1,1,1,2,2,1,1,1,1,1
	dc.b 1,1,2,2,1,1,1,1,2,2,1,1,2,2,1,1,1,1,1,2,1,1,1,1,1,2,2,1,1,1,1,1
	dc.b 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
	dc.b 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1



******** datas
*	variables
LOG_TAB_ADR_PT:	dc.l	TAB_ADR_PT_1
PHY_TAB_ADR_PT:	dc.l	TAB_ADR_PT_2
TAB_ADR_PT_1:	ds.l	NB_POINT
TAB_ADR_PT_2:	ds.l	NB_POINT

LOG_SCR_ADR:	dc.l	ecran1
PHY_SCR_ADR:	dc.l	ecran2
COPLIST_ADR:	dc.l	coplist

SIN_TAB:	include	'Ram:sin_tab.dat'

	section	ZONE_CHIP,BSS_C
	
ecran1:		ds.l	(SCR_SIZE*2)/4
ecran2:		ds.l	(SCR_SIZE*2)/4
coplist:	ds.l	100
	end		

Listing 2 : Makesinus.GFA

OPEN "O",#1,"ram:sin_tab.dat"
FOR i=0 TO 512-1 STEP 8
  FOR j=0 TO 7
    n=SIN((i+j)*PI/256)
    IF j=0
      PRINT #1,CHR$(9)+"dc.w"+CHR$(9);
    ELSE
      PRINT #1,",";
    ENDIF
    IF n=1
      n=0.9999999
    ENDIF
    PRINT #1,"$";HEX$(INT(n*32768),4);
  NEXT j
  PRINT #1,CHR$(10);
NEXT i
CLOSE #1
END


[Retour en haut] / [Retour aux articles]