* Text Viewer
* v. 1.0
* Par Christophe LARATTE
* Pour le Petit Amiga Illustré

* Je n'utilise pas les includes afin de faciliter la compilation (+ rapide)

* Par contre j'utilise beaucoup les labels locaux (avec un point devant)
* Ex : .Cont
* Ces labels ne sont définis qu'entre deux labels normaux
* Ex :
* New	move.l	d0,d1
* 	beq.s	.Cont
*	moveq	#0,d1
* .Cont	rts
*
* Open	...
*
* Ainsi .Cont n'est défini qu'entre New et Open. Son utilisation est
* limitée à cette portion. En dehors il n'est pas reconnu (après Open
* ou avant New). Vous pouvez ainsi définir plusieurs labels locaux
* ayant le même nom mais dans des routines séparées (par des labels
* normaux). Les plus utilisés (par moi) sont .End qui correspond à la
* fin d'une routine et qui sert pour les branchement en cas d'erreur
* par exemple. Les autres sont .Cont, .Cont0, .Cont1, etc. qui permettent
* de faire des branchements conditionnels (voir le source).
* ATTENTION : l'utilisation de ces labels ne marche pas avec tous les
* assembleurs.
* Quand vous compilez avec l'option "débug" qui crée un hunk debug, les
* labels locaux disparaissent. (ça évite d'avoir trop de labels).

* Dos.library
Close			=	-36
Examine			=	-102
Lock			=	-84
Open			=	-30
UnLock			=	-90
Read			=	-42
Write			=	-48

MODE_OLDFILE		=	1005
ACCESS_READ		=	-2

* Exec.library
AllocMem		=	-198
AvailMem		=	-216
CloseLibrary		=	-414
CopyMem			=	-624
FreeMem			=	-210
GetMsg			=	-372
OpenLibrary		=	-552
ReplyMsg		=	-378
TypeOfMem		=	-534
WaitPort		=	-384

* Graphics.library
BltBitMap		=	-30
Move			=	-240
RectFill		=	-306
ScrollRaster		=	-396
SetAPen			=	-342
Text			=	-60

* Intuition.library
CloseScreen		=	-066
CloseWindow		=	-072
OpenScreen		=	-198
OpenWindow		=	-204
RefreshGList		=	-432
ShowTitle		=	-282
ViewPortAddress		=	-300

wd_RPort		=	$32
wd_UserPort		=	$56

Class			=	$14
Code			=	$18
MouseY			=	$22


* Req.library

REQVERSION		=	1
FileRequester		=	-$54
RealTimeScroll		=	-$A8
SetLocation		=	-$2A
SetSize			=	-$24

	move.l	4.w,a6			Ouverture de la req.library
	moveq	#REQVERSION,d0
	lea	ReqName(pc),a1
	jsr	OpenLibrary(a6)
	lea	_ReqBase(pc),a0
	move.l	d0,(a0)
	beq	NoReq

	move.l	d0,a0			Dans la structure de la req
	lea	_DosBase(pc),a1		on trouve des pointeurs
	move.l	4+34(a0),(a1)		correspondant à DosBase, etc.
	lea	_IntuitionBase(pc),a1	Ainsi on gagne du temps en les
	move.l	8+34(a0),(a1)		recopiant plutôt qu'en faisant
	lea	_GfxBase(pc),a1		des OpenLibrary.
	move.l	12+34(a0),(a1)		Mais on ne doit pas les utiliser
				      ; après fermeture de la req.

	move.l	_IntuitionBase(pc),a6	Ouverture de l'écran
	lea	NewScreen(pc),a0
	jsr	OpenScreen(a6)
	lea	Screen(pc),a0
	move.l	d0,(a0)
	beq	NoScreen

	lea	NewWindow(pc),a0	Ouverture de la fenêtre
	jsr	OpenWindow(a6)
	lea	Window(pc),a0
	move.l	d0,(a0)
	beq	NoWindow

	jsr	ViewPortAddress(a6)	Sauvegarde des ports
	lea	ViewPort(pc),a0
	move.l	d0,(a0)
	move.l	Window(pc),a0
	lea	RastPort(pc),a1
	move.l	wd_RPort(a0),(a1)
	lea	UserPort(pc),a1
	move.l	wd_UserPort(a0),(a1)

Attente	move.l	4.w,a6			Attend une action
	move.l	UserPort(pc),a4
	move.l	a4,a0
	jsr	WaitPort(a6)
	move.l	a4,a0
	jsr	GetMsg(a6)
	move.l	d0,a1
	move.l	Class(a1),a3
	move.w	Code(a1),a2
	move.w	MouseY(a1),d2
	jsr	ReplyMsg(a6)
	cmp.l	#$20,a3
	beq	TraiteScroll
	cmp.l	#8,a3		si on appuie
	bne.s	Attente		sur le bouton droit
	cmp.w	#$69,a2		c'est la fin...
	beq	END
	cmp.w	#$68,a2		si c'est le gauche alors
	beq.s	LoadFile	on charge un nouveau fichier
	bra.s	Attente

LoadFile
	lea	FR(pc),a0
	bclr	#3,32(a0)	| positionne les bits du FR pour que la req
	bset	#4,32(a0)	| sache qu'on veut charger un fichier
	move.l	_ReqBase(pc),a6
	jsr	FileRequester(a6)	Affiche le FileRequester
	cmp.l	#1,d0
	bne	.End
	lea	FRCompletePath(pc),a2
	move.l	_DosBase(pc),a6
	move.l	a2,d1
	moveq	#ACCESS_READ,d2
	jsr	Lock(a6)		Réserve le fichier en lecture
	move.l	d0,a3
	move.l	d0,d1
	beq	.End		si réservation impossible alors on s'arrète
	lea	FIB(pc),a0
	move.l	a0,d2
	jsr	Examine(a6)	cette fonction copie dans la structure
	cmp.l	#-1,d0		FileInfoBlock (FIB) des Info concernant
	beq.s	.Cont		le fichier et notamment sa longueur
	move.l	#0,a2
.Cont	move.l	a3,d1
	jsr	UnLock(a6)	plus besoin de réservation
	move.l	a2,d4		(elle ne servait que pour Examine())
	beq	.End
	move.l	4.w,a6
	move.l	FileAddress(pc),d0	s'il y avait déjà un fichier
	tst.l	d0			en mémoire il faut libérer
	beq.s	.Cont0			sa place avant de s'occuper
	move.l	d0,a1			de l'autre (on ne le fait pas
	move.l	FileLength(pc),d0	avant au cas où le fichier
	jsr	FreeMem(a6)		choisi dans le FR n'existe pas)
.Cont0	move.l	FIBSize(pc),d0	On essaie d'allouer de la mémoire
	move.l	#$10001,d1	public pleine de zéros ($10001)
	jsr	AllocMem(a6)	pouvant loger notre fichier (FIBSize)
	tst.l	d0		S'il n'y en a pas avant midi, je change
	beq	.End		de crèmerie
	move.l	d0,a2
	lea	FileLength(pc),a0	initialisation des variables
	move.l	FIBSize(pc),(a0)
	lea	FileAddress(pc),a0	on regarde quel type de
	move.l	d0,(a0)			mémoire on a alloué
	move.l	d0,a1			si c'est de la CHIP
	jsr	TypeOfMem(a6)		ce n'est pa la peine d'en allouer
	btst	#1,d0			d'autre pour le chargement (qui
	bne	.Jump			doit se faire en CHIP)
	move.l	#$20002,d1	si ce n'est pas de la CHIP, on regarde
	jsr	AvailMem(a6)	quel est le plus grand bloc disponible
	cmp.l	FIBSize(pc),d0	en CHIP ($20002) avec AvailMem()
	blt.s	.Cont1
	move.l	FIBSize(pc),d0	si le bloc est plus grand que le fichier
.Cont1	move.l	d0,d5		on a pas besoin de le réserver entièrement
	move.l	#$10002,d1
	jsr	AllocMem(a6)
	tst.l	d0
	bne.s	.Cont2			si l'allocation a échoué on
	move.l	FileAddress(pc),a1	doit libérer le premier bloc
	move.l	FileLength(pc),d0	de mémoire alloué avant de
	jsr	FreeMem(a6)		dire au revoir
	move.l	FileAddress(pc),a0	et aussi réinitialiser
	move.l	#0,(a0)			les variables
	move.l	FileLength(pc),d0
	move.l	#0,(a0)
	bra	.End
.Cont2	move.l	d0,a3
	bsr	.Open			on ouvre le fichier
	bne.s	.Cont3			si c'est raté on
	bsr.s	.Free			libère et on quitte
	bra.s	.End
.Cont3	move.l	FIBSize(pc),d6		calcul le nombre
	divu	d5,d6			de tours à effectuer
	swap	d6			pour tout charger
	tst.w	d6
	beq.s	.Cont4
	move.w	#0,d6
	add.l	#$10000,d6
.Cont4	swap	d6
.Boucle	tst.l	d6
	beq.s	.End00
	move.l	_DosBase(pc),a6		lit une partie du fichier
	move.l	d4,d1			dans le buffer
	move.l	a3,d2			qui se situe en CHIP
	move.l	d5,d3
	jsr	Read(a6)
	cmp.l	#-1,d0		si la lecture a échouée on ferme
	bne.s	.Cont5		on libère et on fuit
	bsr.s	.Free
	bsr.s	.Close
	bra.s	.End
.Cont5	move.l	d0,-(sp)
	beq.s	.MJump		copie la partie du fichier chargée
	move.l	a3,a0		en CHIP en PUBLIC (généralement FAST)
	move.l	a2,a1
	move.l	4.w,a6
	jsr	CopyMem(a6)
.MJump	add.l	(sp)+,a2
	subq.l	#1,d6
	bra.s	.Boucle		c'est une boucle !
.End00	bsr.s	.Free		une fois qu'on a tout chargé et copié
	bsr.s	.Close		on peut fermer, libérer, et partir
	bra.s	.End0		à l'affichage

.Jump	bsr.s	.Open		routine beaucoup plus rapide
	beq.s	.End		qui se contente de charger d'un
	move.l	d4,d1		coup tout le fichier en CHIP
	move.l	a2,d2		(cette routine est appelée sur les
	move.l	FIBSize(pc),d3	Amiga ne possédant que de la CHIP
	jsr	Read(a6)	ou dont la FAST est pleine)
	bsr.s	.Close
.End0	bsr	ResetGadget	on réactualise le gadget
	move.l	FileAddress(pc),a5
	bsr	RedrawDisplay	on fini par afficher le début du fichier
.End	bra	Attente		et on retourne à l'attente

.Free	move.l	4.w,a6
	move.l	a3,a1
	move.l	d5,d0
	jsr	FreeMem(a6)
	rts

.Open	move.l	_DosBase(pc),a6		routine locale qui est chargée
	move.l	d4,d1			d'ouvrir le fichier
	move.l	#MODE_OLDFILE,d2
	jsr	Open(a6)
	move.l	d0,d4
	rts

.Close	move.l	_DosBase(pc),a6		routine locale qui ferme
	move.l	d4,d1			le fichier
	jsr	Close(a6)
	rts

TraiteScroll
	move.l	_ReqBase(pc),a6
	lea	ScrollStruct(pc),a0
	jsr	RealTimeScroll(a6)
	bra	Attente

END	move.l	FileAddress(pc),d0	on vérifie qu'il n'y a
	tst.l	d0			pas de mémoire allouée
	beq.s	.Cont			si c'est le cas et bien
	move.l	d0,a1			on la libère !
	move.l	FileLength(pc),d0
	move.l	4.w,a6
	jsr	FreeMem(a6)
.Cont	move.l	_IntuitionBase(pc),a6
	move.l	Window(pc),a0
	jsr	CloseWindow(a6)
NoWindow
	move.l	Screen(pc),a0
	jsr	CloseScreen(a6)
NoScreen
	move.l	4.w,a6
	move.l	_ReqBase(pc),a1
	jsr	CloseLibrary(a6)
NoReq	moveq	#0,d0
	rts


*  Supers routines   *

ScrollAndDraw
	movem.l	d0-a6,-(sp)
	movem.l	d0/d1/d3/a0,-(sp)
	move.l	_GfxBase(pc),a6
	move.l	RastPort(pc),a1
	move.l	4(a1),a1		On prend le BitMap (voir scrolling1)
	move.l	a1,a0
	move.w	#11,d1
	move.w	d1,d3
	move.w	#240,d5
	tst.w	d2
	bmi.s	.Cont0
	add.w	d2,d1
	sub.w	d2,d5
	bra.s	.Cont1
.Cont0	sub.w	d2,d3
	add.w	d2,d5
.Cont1	move.w	d1,-(sp)
	move.w	d2,-(sp)
	move.w	#16,d0
	move.w	d0,d2
	move.w	#624,d4
	move.b	#$C0,d6
	moveq	#1,d7
	jsr	BltBitMap(a6)
 ; BltBitMap nécessite :
 ; en A0 le BitMap source
 ; en A1 le BitMap destination
 ; pour nous A0 = A1 car on déplace des données dans un seul BitMap
 ; D0,D1 : SrcX et SrcY
 ; D2,D3 : DestX et DestY
 ; D4,D5 : SizeX et SizeY
 ; D6 : Minterm -> mode de copie : $C0 = vanilla copy (déplacement)
 ; d7 : Mask -> nombre de plans ici 1 (le premier) ainsi quelque soit
 ; le nombre de plans total, la vitesse ne change pas.
 ; A2 : TempA   c'est pour les débordements on s'en occupe pas
 ; (on ne déborde jamais !)
	move.w	d2,d0
	move.w	(sp)+,d6
	tst.w	d6
	bmi.s	.Cont2			cette fois on ne déplace plus
	move.w	d3,d1			mais on efface
	add.w	d5,d1			quoi ?
	sub.w	(sp)+,d3		la partie où l'on va écrire
	neg.w	d3			c.a.d soit en haut, soit en bas
	bra.s	.Cont3			pour ce faire on utilise encore
.Cont2	move.w	(sp)+,d1		BltBitMap pour le sport car
	sub.w	d1,d3			on aurait très bien utiliser
.Cont3	move.w	d3,d5			RectFill ou encore BltClear
	move.w	d1,d3			je ne sais d'ailleurs pas quelle
	move.l	RastPort(pc),a1		est la fonction la plus rapide
	move.l	4(a1),a1		à vous d'essayer !
	move.l	a1,a0			Pour BltBitMap comme on ne déplace
	move.b	#0,d6			pas, il suffit de mettre les mêmes
	moveq	#1,d7			valeurs en Src et en Dest
	jsr	BltBitMap(a6)		le Minterm (D6) est lui à 0.
	movem.l	(sp)+,d0/d1/d3/a0
	tst.l	d3
	beq.s	.End
	move.w	d1,d4			d4 : OffsetY
	bsr	CalculFilePos		a5 : Adresse de la 1ère ligne
	move.l	FileLength(pc),d0
	move.l	FileAddress(pc),a3
	add.l	d0,a3			a3 : fin du fichier
	add.w	#17,d4			à afficher
.Boucle	subq.l	#1,d3
	bmi.s	.End
	move.l	RastPort(pc),a1
	moveq	#16,d0
	move.w	d4,d1
	jsr	Move(a6)
	bsr	FindLineSize
	move.l	RastPort(pc),a1
	jsr	Text(a6)
	addq.w	#8,d4
	bra.s	.Boucle
.End	movem.l	(sp)+,d0-a6
	rts


RedrawAll
	movem.l	d0-a6,-(sp)
	move.l	TopEntryNumber(pc),d0
	bsr	CalculFilePos
	bsr	RedrawDisplay
	movem.l	(sp)+,d0-a6
	rts

CalculFilePos
	nop
	tst.l	d0			calcule la position de la ligne
	bne.s	.Cont0			donnée en D0 dans le fichier
	move.l	FileAddress(pc),a5
	bra.s	.End
.Cont0	move.l	FilePos(pc),a5
	move.l	FileLine(pc),d2		pour augmenter la vitesse de
	cmp.l	d0,d2			calcule on utilise le résultat
	beq.s	.End			précédent et on regarde si la
	bgt.s	.Second			nouvelle ligne est avant ou
.Boucle	moveq	#0,d1			après l'ancienne suivant le cas
.MBou	cmp.b	#10,(a5)+		on se branche sur l'une des routines
	beq.s	.End0
	addq.b	#1,d1
	cmp.b	#79,d1
	bne.s	.MBou
	sub.l	#1,a5
.End0	addq.l	#1,d2
	cmp.l	d2,d0
	bne.s	.Boucle
	bra.s	.End
.Second	move.l	FileAddress(pc),a1
.Boucl2	moveq	#0,d1
	cmp.b	#10,-1(a5)
	bne.s	.NBou
	sub.l	#1,a5
.NBou	cmp.b	#10,-(a5)
	beq.s	.End1
	addq.b	#1,d1
	cmp.l	a5,a1
	bne.s	.NBou
.End1	cmp.b	#10,(a5)
	bne.s	.Cont
	add.l	#1,a5
.Cont	cmp.l	#78,d1
	ble.s	.End2
	divu	#78,d1
	mulu	#78,d1
	add.l	d1,a5
.End2	subq.l	#1,d2
	cmp.l	d2,d0
	bne.s	.Boucl2
.End	lea	FilePos(pc),a0
	move.l	a5,(a0)
	lea	FileLine(pc),a0
	move.l	d0,(a0)
	rts

RedrawDisplay
	move.l	_GfxBase(pc),a6		affiche sur tout l'écran
	moveq	#0,d0			cette fonction est appelée
	move.l	RastPort(pc),a1		au moment du chargement
	jsr	SetAPen(a6)		afin de réinitialiser l'écran
	move.l	RastPort(pc),a1		et elle est aussi appelée par
	moveq	#16,d0			RedrawAll
	moveq	#11,d1
	move.w	#639,d2
	move.w	#255,d3
	jsr	RectFill(a6)
	moveq	#1,d0
	move.l	RastPort(pc),a1
	jsr	SetAPen(a6)
	move.l	FileLength(pc),d0
	move.l	FileAddress(pc),a3
	add.l	d0,a3			a3 : fin du fichier
	moveq	#0,d4			a5 : Adresse de la 1ère ligne
.Boucle	move.l	RastPort(pc),a1		à afficher
	moveq	#16,d0
	move.l	d4,d1
	lsl.l	#3,d1
	add.w	#17,d1
	jsr	Move(a6)
	bsr	FindLineSize
	move.l	RastPort(pc),a1
	jsr	Text(a6)
	cmp.l	a5,a3
	ble.s	.End
	addq.b	#1,d4
	cmp.b	#30,d4
	bne.s	.Boucle
.End	rts

FindLineSize
	move.l	a5,a0		cette routine est utilisée par redrawDisplay
	moveq	#0,d0		et par ScrollAndDraw.
	move.l	a0,a1		C'est elle qui détermine la longueur de
.Boucle	cmp.b	#10,(a1)+	chaque ligne
	bne.s	.Cont
	add.l	#1,a5
	bra.s	.End
.Cont	addq.b	#1,d0
	cmp.b	#79,d0
	bne.s	.Boucle
	sub.l	#1,a1
	subq.b	#1,d0
.End	move.l	a1,a5
	cmp.l	a1,a3
	bge.s	.End1
	sub.l	a3,a1
	sub.l	a1,d0
.End1	rts

ResetGadget
	bsr	SetNumEntries		Cette routine réinitialise les
	move.l	_ReqBase(pc),a6		paramètres des structures
	lea	TopEntryNumber(pc),a0	après un chargement de fichier
	move.l	#0,(a0)
	lea	VertPot(pc),a0
	move.w	#0,(a0)
	lea	FilePos(pc),a0
	move.l	FileAddress(pc),(a0)
	lea	FileLine(pc),a0
	move.l	#0,(a0)
	move.l	NumEntries(pc),d0
	move.l	#30,d1
	jsr	SetSize(a6)
 ; SetSize nécessite :
 ; en D0 : le nombre d'entrées (NumEntries)
 ; en D1 : le nombre d'entrées visibles (NumLines)
 ; et il renvoie en D0 la valeur à mettre dans VertBody
 ; A titre d'info SetLocation (que nous n'utilisons pas aujourd'hui,
 ; mais qui est indispensable si vous scrollez l'affichage aussi par
 ; le clavier) nécessite :
 ; en D0 : le nombre d'entrées (NumEntries)
 ; en D1 : le nombre d'entrées visibles (NumLines)
 ; en D2 : la ligne courante (TopEntryNumber)
 ; c'est simple !
 ; au fait il renvoie en D0 la valeur à mettre dans VertPot
	lea	VertBody(pc),a0
	move.w	d0,(a0)
	move.l	_IntuitionBase(pc),a6
	lea	Gadget(pc),a0
	move.l	Window(pc),a1
	move.l	#0,a2
	moveq	#1,d0
	jsr	RefreshGList(a6)
	rts

SetNumEntries
	move.l	FileAddress(pc),a0	calcule le nombre de ligne
	move.l	FileLength(pc),d3	qu'il y a dans un fichier
	moveq	#1,d2
	move.l	d2,d1
.Boucle	moveq	#0,d0
.MBou	addq.l	#1,d1
	cmp.l	d1,d3
	beq.s	.End
	cmp.b	#10,(a0)+
	beq.s	.End0
	addq.b	#1,d0
	cmp.b	#79,d0
	bne.s	.MBou
	sub.l	#1,a0
.End0	addq.l	#1,d2
	bra.s	.Boucle
.End	lea	NumEntries(pc),a0
	move.l	d2,(a0)
	rts

FileAddress	dc.l	0
FileLength	dc.l	0
FilePos		dc.l	0
FileLine	dc.l	0

ViewPort	dc.l	0
RastPort	dc.l	0
UserPort	dc.l	0

_IntuitionBase	dc.l	0
_GfxBase	dc.l	0
_ReqBase	dc.l	0
_DosBase	dc.l	0

		CNOP	0,4
 ; Je suis sûr que vous ne connaissez pas cette directive d'assemblage !
 ; Vous connaissez "even" ?
 ; (si vous ne connaissez pas reportez-vous à scrolling1)
 ; Cette fonction à le même rôle mais en plus complet :
 ; elle nécessite comme arguments 1 offset et 1 alignement.
 ; Commençons par la fin :
 ; l'alignement indique l'alignement désiré :-)
 ; 1 -> alignement en octet (alignement normal)
 ; 2 -> alignement en mot (comme pour even)
 ; 4 -> alignement en mot long
 ; etc.
 ; l'offset indique le nombre d'octet que doit laisser l'assembleur
 ; par rapport à l'alignement.
 ; Ex : CNOP 3,2
 ; l'assembleur s'alignera sur le prochain octet pair (alignement en mot)
 ; et ajoutera 3 octets à cette position.
 ; Donc CNOP 3,2 correspond à :
 ;                               even
 ;                               dcb.b 3,0
 ;
 ; Maintenant, vous devez vous poser une autre question :
 ; Mais diable à quoi ça sert ?
 ; Dans le cas présent c'est indispensable si vous voulez programmer
 ; "proprement", car la structure qui suit est une structure utilisée
 ; par une fonction de la dos.library, et comme tout le monde le sait
 ; la dos.library utilise des pointeurs BCPL, c.a.d des pointeurs qui
 ; ont été divisé par 4. Ainsi on gagne... heu... sûrement quelque chose.
 ; Or si vous divisez par 4 (LSR.L #2,Dx), vous perdez les 2 derniers bits
 ; qui justement permettent d'avoir une précision de l'ordre de l'octet où
 ; du mot. Ainsi à la prochaine multiplication par 4 (LSL.L #2,Dx), votre
 ; adresse sera forcément alignée sur un mot long puisque vous avez perdu
 ; les 2 bits. Bien sûr quand on parle de structure DOS on ne vous précise
 ; pas tout ça. On vous dit simplement qu'une structure DOS  doit être
 ; alignée sur un mot long, ce que fait le CNOP 0,4.
 ; Une autre méthode pour être sûr que votre structure est sur un mot long
 ; c'est de faire une allocation de mémoire. Malheureusement vous devrez
 ; ensuite la remplir à l'aide de "move.x".


FIB		dcb.b	124,0		structure qui tient beaucoup
FIBSize		dcb.b	136,0		de place et qui est utilisée
				      ; par Examine() pour mettre un
				      ; tas d'infos sur un fichier.
				      ; Nous on s'intèresse qu'à la taille

ScrollStruct
TopEntryNumber	dc.l	0		TopEntryNumber
NumEntries	dc.l	0		NumEntries
		dc.w	8		LineSpacing
		dc.l	30		NumLines
		dc.l	Gadget		PropGadget
		dc.l	RedrawAll	RedrawAll
		dc.l	0		ReadMore
		dc.l	ScrollAndDraw	ScrollAndDraw
		dc.w	REQVERSION	versionnumber
		dc.l	0		rfu1
		dc.l	0		rfu2

FR		dc.w	REQVERSION	VersionNumber
		dc.l	FRTitle		Title
		dc.l	FRPath		Dir
		dc.l	FRName		File
		dc.l	FRCompletePath	PathName
Window		dc.l	0		Window
		dc.w	0		maxExtendedSelect
		dc.w	12		numlines
		dc.w	26		numcolumns
		dc.w	12		devcolumns
		dc.l	$40|$10		Flags
 ; $10 : FRQINFOGADGET -> gadget permettant d'afficher/cacher
 ; les fichiers .info
 ; $40 : FRQABSOLUTEXY -> le FileRequester apparait à la position
 ; déterminée par WindowLeftEdge et WindowTopEdge (et non sous le curseur)
		dc.w	2		dirnamescolor
		dc.w	1		filenamescolor
		dc.w	2		devicenamescolor
		dc.w	0		fontnamescolor
		dc.w	0		fontsizescolor
		dc.w	0		detailcolor
		dc.w	1		blockcolor
		dc.w	1		gadgettextcolor
		dc.w	1		textmessagecolor
		dc.w	0		stringnamecolor
		dc.w	1		stringgadgetcolor
		dc.w	0		boxbordercolor
		dc.w	0		gadgetboxcolor
		dcb.b	36,0		RFU = réservé pour le futur
		dcb.b	12,0		DirDateStamp (réservé)
		dc.w	142		WindowLeftEdge
		dc.w	29		WindowTopEdge
		dc.w	0		FontYSize
		dc.w	0		FontStyle
		dcb.b	240,0		un tas de données réservées

FRTitle		dc.b "Choose a file",0
FRPath		dcb.b	131,0
FRName		dcb.b	31,0
FRCompletePath	dcb.b	162,0

		even

NewWindow	dc.w 0    		LeftEdge
		dc.w 0			TopEdge
		dc.w 640		Width
		dc.w 256		Height
		dc.b 3			DetailPen
		dc.b 1			BlockPen
		dc.l 8|$10|$10000|$1000|$800|$100|$20	IDCMPflags
 ; 8 : MOUSEBUTTON -> dès qu'on appuiera sur un bouton de la souris le
 ; programme sera averti
 ; $10 : MOUVEMOVE -> dès qu'on déplacera la souris, le programme sera averti
 ; $10000 : DELTAMOVE -> les reports dûs à MOUSEMOVE sont transmis en
 ; position relative, c.a.d. par rapport à l'ancienne position

		dc.l $1000|$10000|$100|$800|$20	Flags
 ; $1000 : ACTIVATE -> la fenêtre est active à l'ouverture
 ; $800 : BORDERLESS -> sans bord
 ; $100 : BACKDROP -> la fenêtre est toujours au fond derrière toutes les
 ; autres
 ; $10000 : RMBTRAP -> pas de gestion de menu : on gère le bouton droit
 ; de la souris comme le gauche
 ; $20 : GADGETDOWN -> on a appuyé sur un gadget
		dc.l Gadget		*FirstGadget
		dc.l 0			*CheckMark
		dc.l 0			*Title   (ASCII)
Screen		dc.l 0			*Screen
		dc.l 0			*Bitmap
		dc.w 0			MinWidth
		dc.w 0			MinHeight
		dc.w 0			MaxWidth (-1 : max)
		dc.w 0			MaxHeight
		dc.w $F			Type ($f : CUSTOMSCREEN)


NewScreen	dc.w 0    		LeftEdge
		dc.w 0			TopEdge
		dc.w 640		Width
		dc.w 256		Height
		dc.w 2			Depth
		dc.b 0			DetailPen
		dc.b 1			BlockPen
		dc.w $8000		ViewModes
		dc.w $1F		Type ($f : CUSTOMSCREEN)
		dc.l 0			Font
		dc.l Title		DefaultTitle
		dc.l 0			Gadgets
		dc.l 0			CustomBitMap

Gadget		dc.l 0			NextGadget
		dc.w 0			LeftEdge
		dc.w 11			TopEdge
		dc.w 15			Width
		dc.w 240		Height
		dc.w 0			Flags
		dc.w 2			Activation
 ; 2 : GADGIMMEDIATE -> avertie le programme dès qu'on appuie sur le gadget
		dc.w 3			GadgetType
 ; 3 : PROPGADGET -> gadget proportionnel (ascenseur)
		dc.l Image		GadgetRender
		dc.l 0			SelectRender
		dc.l 0			GadgetText
		dc.l 0			MutualExclude
		dc.l PropInfo		SpecialInfo
		dc.w 0			GadgetID
		dc.l 0			UserData

Image		dc.w 0			LeftEdge	\
		dc.w 0			TopEdge		| étant donné que
		dc.w 0			Width		| dans PropInfo, on
		dc.w 0			Height		| a mis AUTOKNOB
		dc.w 0			Depth		| intuition mettra
		dc.l 0			*ImageData	| dans cette
		dc.b 0			PlanePick	| structure
		dc.b 0			planeOnOff	| tout ce qu'il veut
		dc.l 0			*NextImage	/

PropInfo	dc.w 1+4		Flags
 ; 1 : AUTOKNOB -> c'est intution qui se charge de dessiner le "KNOB"
 ; c.a.d l'ascenseur
 ; 4 : FREEVERT -> le "KNOB" peut bouger verticalement
		dc.w 0			HorizPot
VertPot		dc.w 0			VertPot
 ; HorizPot et VertPot désignent les positions relatives de l'ascenseur
 ; dans le gadget. Ces positions sont données en fraction (comprises
 ; entre 0 et 1).
 ; On ne s'occupe que de VertPot étant donné qu'on ne bouge que verticalement
 ; Quand on veut le modifier on fait appel à la fonction de la req.library
 ; SetLocation. Ca évite les calculs fastidieux.
		dc.w 0			HorizBody
VertBody	dc.w -1			VertBody
 ; HorizBody et VertBody précisent la taille du "KNOB" par rapport à
 ; celle du gadget, toujours en fraction.
 ; on ne s'occupe que de VertBody. A l'initialisation on le met à -1
 ; car il occupe tout le gadget.
 ; Ensuite pour modifier sa valeur on appelle aussi une fonction de la req
 ; SetSize.
		dc.w 0			CWidth		\ intuition
		dc.w 0			CHeight		| s'en occupe
		dc.w 0,0		HPotRes,VPotRes	| tout seul
		dc.w 0			LeftBorder	| c'est toujours
		dc.w 0			TopBorder	/ ça de moins

Title		dc.b	"Text Viewer v. 1.0 par Christophe LARATTE pour le Petit Amiga Illustré",0

ReqName	dc.b	"req.library",0

	END
