ping.asm
blupi-games_smaky-legacy/ping/src/ping.asm
	.TITLE	PING

;	--------------------------------------
;		(C) 1987 - Daniel Roux
;	--------------------------------------

	.PROC	M680002
	.REF	SMAKY
	.REF	GRA


	.REV	1,0
	.CODE	800,2,B'1111,600,2000,300,2000,2,'N,'R,'F,09
	.TEXT	"(C)  Daniel ROUX et EPSITEC-system sa"


IFSMILE	=	0		; 1 => assemblage pour SMILE2



; En-tte d'un fichier .IMAGE
; ---------------------------

	.LOC	0
OIMTYP:	.BLKB	1		; H'01 = indique type image
OIMCOD:	.BLKB	1		; H'00 = indique pas de codage
OIMBIP:	.BLKB	1		; H'01 = 1 bit par point
OIMDIR:	.BLKB	1		; H'02 = coord. X-Y comme cran
OIMDLX:	.BLKB	2		; largeur image en points
OIMDLY:	.BLKB	2		; hauteur image en points
OIMNBB:	.BLKB	4		; nb de byte pour l'image
	.BLKB	20		; rserve
LGHIMA:


; Dfinition de l'entte d'un gnrateur de caractres
; ----------------------------------------------------

OGCMSB	=	H'04		; matrix size in bytes
OGCMHD	=	H'06		; matrix height in dots
OGCMWB	=	H'08		; matrix width in bytes
OGCFCA	=	H'0A		; ASCII code of first character
OGCLCA	=	H'0B		; ASCII code of last character
OGCLMA	=	H'0C		; left margin of matrix
OGCBLI	=	H'0E		; bottom of matrix to baseline
OGCISP	=	H'16		; interline space in dots
OGCWID	=	256		; 128 x width
OGCH1	=	256+128*1	; 128 x h1
OGCH2	=	256+128*2	; 128 x h2
OGCMAT	=	256+128*3	; 128 x matrix




; Constantes
; ----------

MAXPOINT=	21		; nb de points pour gagner

VIT1	=	50/8		; vitesse 1:  8 images/seconde
VIT2	=	50/14		; vitesse 1: 14 images/seconde
VIT3	=	50/25		; vitesse 1: 25 images/seconde

MAXVITX	=	30		; vitesse maximale en X
MAXVITY	=	30		; vitesse maximale en Y

MAXVITS	=	10		; vitesse maximale raquette SMAKY

MAXIRAQ	=	7		; inclinaison maximale (45 degrs)




; Caractres standard
; -------------------

GCTXF	=	'N		; fonte (N)
GCTXS	=	'R!2^7		; style/chasse (RF)
GCTXT	=	09		; taille (09)



; Icnes des IPP64
; ----------------

GCICF	=	'I		; fonte (I)
GCICS	=	'P		; style/chasse (PP)
GCICT	=	64		; taille (64)


VTANIME	=	2		; vitesse de l'animation de fin
NBANIME	=	5+1		; nb d'icnes d'animation (+1 vide)

ICOBALLE1=	32		; balle 1
IDXBALLE1=	17
IDYBALLE1=	17

ICORAQJ	=	71		; raquette horizontale du joueur
ICORAQS	=	71+16		; raquette horizontale du SMAKY
IDXRAQ	=	64
IDYRAQ	=	64
ICXRAQ	=	31
ICYRAQ	=	20

NBABRI	=	8		; nb d'icnes d'animation des briques casses

ICOBRIQUE=	96		; brique du mur de sparation
IDXBRI	=	35
IDYBRI	=	20



; Positions dans l'image
; ----------------------

LXWDO	=	640		; largeur de l'cran
LYWDO	=	340		; hauteur de l'cran

MARGH	=	41		; marge en haut
MARGB	=	33		; marge en bas
MARGG	=	9		; marge  gauche
MARGD	=	10		; marge  droite

FRONTX	=	MARGG+((LXWDO-MARGG-MARGD)/2)-1 ; frontire entre les deux camps

POSYRAQ	=	LYWDO-IDYRAQ-33	; position Y de la raquette
POSXRAQ	=	133		; position X de la raquette fixe

RAQEL	=	10		; lvation pour le bouton du milieu

MAXBRI	=	8		; nb max de briques
POSXBRI	=	FRONTX-(IDXBRI/2) ; position X d'une brique
POSYBRI	=	LYWDO-57	; position Y d'une brique tout en bas

POSYCJ	=	LYWDO-316	; position du compteur du joueur
POSXCJ	=	265

POSYCS	=	LYWDO-316	; position du compteur du SMAKY
POSXCS	=	357

POSYSJ	=	LYWDO-327	; position service du joueur
POSXSJ	=	26

POSYSS	=	LYWDO-327	; position service du SMAKY
POSXSS	=	600





; Description d'une raquette
; --------------------------

	.LOC	0
ORAQPO:	.BLKB	4		; raquette: position (y;x)
ORAQIN:	.BLKB	2		; raquette: inclinaison
ORAQEL:	.BLKB	2		; raquette: lvation pour tir
ORAQIC:	.BLKB	1		; raquette: icne
ORAQET:	.BLKB	1		; raquette: tat
 BRAQL	=  0			;  bouton gauche press
 BRAQR	=  1			;  bouton droite press
 BRAQG	=  2			;  clavier pour avancer  gauche
 BRAQD	=  3			;  clavier pour avancer  droite
 BRAQS	=  7			;  service (on lance la balle)
	.EVEN
ORAQDX:	.BLKB	2		; raquette: minimum en X
ORAQFX:	.BLKB	2		; raquette: maximum en X
LRAQ:


; Descripteur d'un objet en chute libre
; -------------------------------------

	.LOC	0
OOBPOS:	.BLKB	4		; position (y;x) au temps t
OOBPOO:	.BLKB	4		; position (y;x) au temps t-1
OOBDIM:	.BLKB	4		; dimensions (dy;dx)
OOBVIT:	.BLKB	4		; vitesses (vy;vx)
OOBCHO:	.BLKB	4		; amortissement en cas de choc (ay;ax)
OOBACC:	.BLKB	2		; pesanteur (py)
OOBVIM:	.BLKB	2		; dure de vie maximale
OOBVIE:	.BLKB	2		; dure de vie de l'objet
OOBFIN:	.BLKB	2		; dure de fin de l'objet
OOBVIF:	.BLKB	2		; compteur de vitesse de fin
OOBICO:	.BLKB	1		; code de l'icne
OOBNEW:	.BLKB	1		; 1 => nouvel objet
OOBOLD:	.BLKB	1		; 1 => objet mort
	.EVEN
OOBMU1:	.BLKB	2		; bruit: choc avec un bord
OOBMU2:	.BLKB	2		; bruit: choc avec la raquette
OOBMU3:	.BLKB	2		; bruit: mort de l'objet
LOBJ:



; Variables
; ---------

	.LOC	0

OMACHINE:.BLKB	1		; type de la machine (SMAKY8/SMAKY100)
OINV:	.BLKB	1		; 1 => fond de l'cran blanc
	.EVEN

OPDDIS:	.BLKB	4		; ^descripteur de la fentre
OPGICO:	.BLKB	4		; ^gencar des icnes (IPP64)
OADRASTER:	.BLKB	4	;  adresse de GRA_RASTER
OADMATRIX:	.BLKB	4	;  adresse de GRA_MATRIX
OADDOT:		.BLKB	4	;  adresse de GRA_DOT
OADTRAME:	.BLKB	4	;  adresse de GRA_TRAME
OADLINE:	.BLKB	4	;  adresse de GRA_LINE
OADELLIPSE:	.BLKB	4	;  adresse de GRA_ELLIPSE
OADFILLO:	.BLKB	4	;  adresse de GRA_FILLO
OADFILLC:	.BLKB	4	;  adresse de GRA_FILLC
OADCLEAR:	.BLKB	4	;  adresse de GRA_CLEAR
OADSET:		.BLKB	4	;  adresse de GRA_SET
OADINV:		.BLKB	4	;  adresse de GRA_INV
OADQXDOT:	.BLKB	4	;  adresse de GRA_QXDOT
OBUDIS:	.BLKB	100		; buffer write-display

OPIMA:	.BLKB	4		; ^image principale du jeu
ODIMA:	.BLKB	4		; dimensions image

OMOUPO:	.BLKB	4		; souris: position

ORAQJ:	.BLKB	LRAQ		; raquette du joueur
ORAQS:	.BLKB	LRAQ		; raquette du SMAKY
OBALLE:	.BLKB	LOBJ		; balle principale
OSIMBA:	.BLKB	LOBJ		; balle de simulation
OBRIQUE:.BLKB	2*(MAXBRI+1)	; tat des briques
OBRINB:	.BLKB	2		; nb de briques

OTIMING:.BLKB	2		; dure d'une image (unit 20ms)
OMODE:	.BLKB	1		; mode gnral
 BVIT1	=  0			;  vitesse lente
 BVIT2	=  1			;  vitesse moyenne
 BVIT3	=  2			;  vitesse rapide
 BFACILE=  4			;  pour dbutants

OFIXE:	.BLKB	1		; 1 => raquette fixe
OBEGIN:	.BLKB	1		; 1 => dbut du jeu
OEND:	.BLKB	1		; 1 => fin de la partie
OHELP:	.BLKB	1		; 1 => appel  l'aide
OGAGNE:	.BLKB	1		; 1 => partie gagne
OPERDU:	.BLKB	1		; 1 => partie perdue
OSTRAT:	.BLKB	1		; stratgie du SMAKY
	.EVEN

OFONCT:	.BLKB	2		; fond: compteur pour le frottement

OSERV:	.BLKB	1		; indicateurs de servide
OCOMP:	.BLKB	1		; compteurs allums
	.EVEN
OCOMPF:	.BLKW	1		; frquence de clignottement des compteurs

OCONJ:	.BLKB	2		; compteur du joueur
OCONS:	.BLKB	2		; compteur du SMAKY

OHAZA:	.BLKB	8		; registre 63 bits pour gnrateur alatoire

OTIME:	.BLKB	4		; marque le temps de dbut

LGVAR:





; Programme principal
; -------------------

	.LOC	0
START:
	.IF	~IFSMILE
	LIB	?OPELIB
	.ENDIF

	LOAD.L	D4,#LGVAR
	LOAD.W	D1,#MTYPCP
	GESMEM	?GETMEM		; demande mmoire pour variables
	JUMP,NE ERFAT
	LOAD.L	A6,A4		; A6 <-- ^variables
10$:
	CLR.B	(A4+)		; met toutes les variables  zro
	DEC.W	D4
	JUMP,NE 10$

	LOAD.W	D3,#3
	LIB	?MOUSE		; souris par le clavier

	LOAD.W	D4,#1
	LIB	?WAITMOUSE	; souris reprsente par une flche


	NTREL	?GETMACHINE	; D4/A3 <-- paramtres
	RL.L	D4,#8		; D4 <-- type de la machine
	LOAD.B	(A6)+OMACHINE,D4


	LIB	?GCHDIS		; D6 <-- canal cran
	LOAD.W	D3,#TYPWDO	; D3 <-- type fentre cran
	LOAD.L	D4,#4		; D4 <-- longueur demande
	LOAD.L	A4,#(A6)+OPDDIS	; A4 <-- ^buffer
	FOS	?RSTATUS	; demande le ^rel !
	JUMP,NE ERFAT
	LOAD.L	A0,(A6)+OPDDIS	; A0 <-- ^descripteur de la fentre <<PREMANANT>>


	LOAD.W	D3,#GRA_RASTER
	LIB_	GETAD
	JUMP,NE ERFAT
	LOAD.L	(A6)+OADRASTER,A3

	LOAD.W	D3,#GRA_MATRIX
	LIB_	GETAD
	JUMP,NE ERFAT
	LOAD.L	(A6)+OADMATRIX,A3

	LOAD.W	D3,#GRA_DOT
	LIB_	GETAD
	JUMP,NE ERFAT
	LOAD.L	(A6)+OADDOT,A3

	LOAD.W	D3,#GRA_TRAME
	LIB_	GETAD
	JUMP,NE ERFAT
	LOAD.L	(A6)+OADTRAME,A3

	LOAD.W	D3,#GRA_LINE
	LIB_	GETAD
	JUMP,NE ERFAT
	LOAD.L	(A6)+OADLINE,A3

	LOAD.W	D3,#GRA_ELLIPSE
	LIB_	GETAD
	JUMP,NE ERFAT
	LOAD.L	(A6)+OADELLIPSE,A3

	LOAD.W	D3,#GRA_FILLO
	LIB_	GETAD
	JUMP,NE ERFAT
	LOAD.L	(A6)+OADFILLO,A3

	LOAD.W	D3,#GRA_FILLC
	LIB_	GETAD
	JUMP,NE ERFAT
	LOAD.L	(A6)+OADFILLC,A3

	LOAD.W	D3,#GRA_CLEAR
	LIB_	GETAD
	JUMP,NE ERFAT
	LOAD.L	(A6)+OADCLEAR,A3

	LOAD.W	D3,#GRA_SET
	LIB_	GETAD
	JUMP,NE ERFAT
	LOAD.L	(A6)+OADSET,A3

	LOAD.W	D3,#GRA_INV
	LIB_	GETAD
	JUMP,NE ERFAT
	LOAD.L	(A6)+OADINV,A3

	LOAD.W	D3,#GRA_QXDOT
	LIB_	GETAD
	JUMP,NE ERFAT
	LOAD.L	(A6)+OADQXDOT,A3


	LIB	?AFTIM
	.B	NOCURS		; pas de curseur !
	.B	AFCCMO		; pas de flche-souris
	.B	LOADGC		; charge les caractres standards
	.B	GCTXF
	.B	GCTXS
	.B	GCTXT
	.B	0
	.EVEN
	JUMP,NE ERFAT

	LIB	?AFTIM
	.B	LOADGC		; charge les icnes IPP64
	.B	GCICF
	.B	GCICS
	.B	GCICT
	.B	0
	.EVEN
	JUMP,NE ERFAT

	LIB	?AFTIM
	.B	USEGC		; utilise les icnes IPP64
	.B	GCICF
	.B	GCICS
	.B	GCICT
	.B	0
	.EVEN
	LOAD.L	(A6)+OPGICO,(A0)+ODFPGC
	LIB	?AFTIM
	.B	USEGC		; charge les caractres standard
	.B	GCTXF
	.B	GCTXS
	.B	GCTXT
	.B	0
	.EVEN

	LOAD.B	D3,#ICOBRIQUE
	LOAD.W	D4,#NBABRI
40$:
	CALL	PREPBRI		; prpare les briques de IMP64
	INC.B	D3
	DEC.W	D4
	JUMP,NE 40$


	SET.B	(A6)+OINV	; le fond de l'cran est blanc
	LOAD.B	(A6)+OMODE,#2^BVIT2
	LOAD.W	(A6)+OTIMING,#VIT2

	LOAD.L	A3,#R16"NMIMA
	CALL	LOADIMAGE	; charge l'image principale de fond
	JUMP,NE	ERFAT
	LOAD.L	(A6)+OPIMA,A4
	LOAD.L	(A6)+ODIMA,D4


	LOAD.W	D4,#LYWDO
	LOAD.W	D3,(A0)+ODFDY
	SUB.W	D3,D4
	SR.W	D3,#1
	SWAP.W	D3
	SWAP.W	D4
	LOAD.W	D4,#LXWDO
	LOAD.W	D3,(A0)+ODFDX
	SUB.W	D3,D4
	SR.W	D3,#1
	LIB	?CREWDO		; cre swdo (utile pour SMAKY 8)
	LIB	?USEWDO


	LOAD.L	A4,#(A6)+ORAQJ	; A4 <-- ^description raquette joueur
	LOAD.B	(A4)+ORAQIC,#ICORAQJ
	LOAD.W	(A4)+ORAQDX,#MARGG+2
	LOAD.W	(A4)+ORAQFX,#FRONTX-32-IDXRAQ

	LOAD.L	A4,#(A6)+ORAQS	; A4 <-- ^description raquette SMAKY
	LOAD.B	(A4)+ORAQIC,#ICORAQS
	LOAD.W	(A4)+ORAQDX,#FRONTX+32
	LOAD.W	(A4)+ORAQFX,#LXWDO-MARGD-IDXRAQ-2


; Affiche la premire image d'aide, totalement statique.

AIDE:
	LOAD.L	A3,#R16"TXMENU0
	LIB	?AFMENU		; affiche les soft-keys

	LOAD.L	A3,#R16"NAIMA
	CALL	AFIMAGE		; affiche l'image d'aide
60$:
	LIB	?GETCAR
	COMP.W	D3,#END
	JUMP,EQ FINI
	COMP.W	D3,#F0
	JUMP,EQ FINI
	COMP.W	D3,#F0+SHIFT
	JUMP,EQ FINI

	COMP.W	D3,#F1
	JUMP,EQ 65$
	COMP.W	D3,#F1+SHIFT
	JUMP,EQ 65$
	COMP.W	D3,#F2
	JUMP,EQ 65$
	COMP.W	D3,#F2+SHIFT
	JUMP,EQ 65$
	COMP.W	D3,#F3
	JUMP,EQ 65$
	COMP.W	D3,#F3+SHIFT
	JUMP,EQ 65$
	COMP.W	D3,#SPACE
	JUMP,NE 60$

; Affiche la deuxime image d'aide, o il est possible d'incliner
; la raquette pour s'y habituer.

65$:
	CLR.B	(A6)+OEND
	CLR.B	(A6)+OHELP
	CLR.B	(A6)+OBEGIN

	LOAD.L	A3,#R16"TXMENU1
	LIB	?AFMENU		; affiche les soft-keys

	PUSH.B	(A6)+OMODE
	PUSH.W	(A6)+OTIMING
	LOAD.B	(A6)+OMODE,#2^BVIT2
	LOAD.W	(A6)+OTIMING,#VIT2
	SET.B	(A6)+OFIXE	; raquette immobile

	LOAD.L	A3,#R16"NRIMA
	CALL	AFIMAGE		; affiche l'image d'aide
	LOAD.L	(A6)+ORAQJ+ORAQPO,#H'10000*POSYRAQ+POSXRAQ
	CLR.W	(A6)+ORAQJ+ORAQIN

	LOAD.L	D4,(A4)+ORAQPO
	SWAP.W	D4
	LOAD.W	D4,#POSYRAQ
	SWAP.W	D4
	CALL	PMOUSE		; met la souris en place
70$:
	CALL	ACTION		; actionne la raquette ...
	TEST.B	(A6)+OEND	; fin de la partie ?
	JUMP,T	75$
	TEST.B	(A6)+OBEGIN	; dbut de la partie ?
	JUMP,F	70$
75$:
	CLR.B	(A6)+OFIXE	; raquette mobile
	POP.W	(A6)+OTIMING
	POP.B	(A6)+OMODE

	TEST.B	(A6)+OEND	; fin de la partie ?
	JUMP,T	FINI


; Nouvelle partie. Remet toutes les briques et redonne 10 balles.

NEWPARTIE:
	LOAD.L	A3,#R16"TXMENU2
	LIB	?AFMENU		; affiche les soft-keys

	LOAD.L	A4,(A6)+OPIMA	; A4 <-- ^image principale
	LOAD.L	D4,(A6)+ODIMA	; D4 <-- dimensions
	CALL	SHOWIMAGE	; affiche l'image de fond

	CLR.B	(A6)+OSERV	; indicateurs de services teints
	CLR.B	(A6)+OCOMP	; compteurs teints
	CLR.W	(A6)+OBRINB	; toutes les briques absentes

	CLR.L	(A6)+ORAQJ+ORAQPO ; la raquette n'existe pas
	CLR.L	(A6)+ORAQS+ORAQPO ; la raquette n'existe pas

	CALL	COUPSAC		; gnrateur alatoire: coup de sac

	LOAD.L	A4,#(A6)+ORAQJ	; A4 <-- descripteur raquette joueur
	CLR.L	(A4)+ORAQPO
	CLR.W	(A4)+ORAQIN
	CLR.W	(A4)+ORAQEL
	LOAD.L	D4,#H'10000*POSYRAQ+(FRONTX-200)
	CLR.W	D3
	CALL	MOVERAQ		; dessine la premire raquette du joueur
	LOAD.L	D4,(A4)+ORAQPO
	CALL	PMOUSE		; et met la souris en place

	LOAD.L	A4,#(A6)+ORAQS	; A4 <-- descripteur raquette SMAKY
	CLR.L	(A4)+ORAQPO
	CLR.W	(A4)+ORAQIN
	CLR.W	(A4)+ORAQEL
	LOAD.L	D4,#H'10000*POSYRAQ+(FRONTX+100)
	CLR.W	D3
	CALL	MOVERAQ		; dessine la premire raquette du SMAKY

	CLR.W	(A6)+OCONJ	; zro ..
	CLR.W	(A6)+OCONS	; ..  zro !

; Nouvelle balle. Laisse les briques dans l'tat o elles sont.

NEWBALLE:
	CLR.B	(A6)+OBEGIN
	CLR.B	(A6)+OEND
	CLR.B	(A6)+OHELP
	CLR.B	(A6)+OGAGNE
	CLR.B	(A6)+OPERDU

	CALL	JCOMPTE		; affiche le compteur du joueur
	CALL	SCOMPTE		; affiche le compteur du SMAKY

	CALL	ALLBRIQUE	; dessine toutes les briques

	CALL	HAZARD		; D4 <-- nombre alatoire
	LOAD.B	(A6)+OSTRAT,D4	; choix de la stratgie du SMAKY

	LOAD.L	A5,#(A6)+OBALLE
	CALL	NEWOBJET	; A5 <-- nouvelle balle

	CALL	NEWSERVICE	; D4 <--  qui le service ?
	TEST.L	D4:#0		; service  faire par le SMAKY ?
	JUMP,BS 30$		; oui => 30$

; Service effectu par le joueur.
; Attend que l'on bouge la souris pour choisir l'emplacement de
; dpart de la balle.

	CALL	JSERVICE

	LOAD.L	A3,#R16"TXMENU3
	LIB	?AFMENU		; affiche les soft-keys

	LOAD.L	A4,#(A6)+ORAQJ	; A4 <-- ^description raquette joueur
	TSET.B	(A4)+ORAQET:#BRAQS ; dbut du service

	LOAD.L	D4,(A4)+ORAQPO	; D4 <-- position
	DEC.W	D4		; D4 <-- pour redessiner avec la balle !!
	SWAP.W	D4
	LOAD.W	D4,#POSYRAQ
	SWAP.W	D4
	LOAD.W	D3,(A4)+ORAQIN	; D3 <-- inclinaison
	CALL	MOVERAQ		; dessine la raquette avec la balle
	LOAD.L	D4,(A4)+ORAQPO
	CALL	PMOUSE		; met la souris o est la raquette !
21$:
	CALL	ACTION		; effectue une action ...
	CALL	VIECOMPTE	; clignottement des compteurs

	TEST.B	(A6)+OHELP	; appel  l'aide ?
	JUMP,T	AIDE

	TEST.B	(A6)+OEND	; fin de la partie ?
	JUMP,T	FINI

	TEST.B	(A6)+OBEGIN	; tir de la balle ?
	JUMP,F	21$

	LOAD.L	A5,#(A6)+OBALLE
;;?	CALL	INVOBJ
	SUB.W	(A5)+OOBPOS+0,#RAQEL ; lve la balle
;;?	CALL	INVOBJ
	JUMP	38$

; Service effectu par le SMAKY.

30$:
	CALL	SSERVICE

	LOAD.L	A4,#(A6)+ORAQS	; A4 <-- ^description raquette SMAK
	TSET.B	(A4)+ORAQET:#BRAQS ; dbut du service

	LOAD.W	D3,(A4)+ORAQDX
	LOAD.W	D4,(A4)+ORAQFX
	SUB.W	D4,#100
	CALL	MMHAZARD	; D4 <-- position de lancement
	LOAD.W	D0,D4		; D0 <-- position  atteindre
31$:
	CALL	ACTION		; effectue une action ...
	CALL	VIECOMPTE	; clignottement des compteurs

	TEST.B	(A6)+OHELP	; appel  l'aide ?
	JUMP,T	AIDE

	TEST.B	(A6)+OEND	; fin de la partie ?
	JUMP,T	FINI

	LOAD.W	D4,(A4)+ORAQPO+2
	COMP.W	D4,D0
	JUMP,EQ 34$
	JUMP,HI 33$
				; avance vers la gauche =>
	ADD.W	D4,#4
	COMP.W	D4,D0
	JUMP,LS 34$
	LOAD.W	D4,D0
	JUMP	34$
33$:				; avance vers la droite =>
	SUB.W	D4,#4
	COMP.W	D4,D0
	JUMP,HS 34$
	LOAD.W	D4,D0
34$:
	LOAD.W	D3,D4
	SUB.W	D3,(A4)+ORAQDX
	MUL.WU	D3,#MAXIRAQ
	LOAD.W	D2,(A4)+ORAQFX
	SUB.W	D2,(A4)+ORAQDX
	DIV.WU	D3,D2
	ADD.W	D3,#3
	COMP.W	D3,#MAXIRAQ
	JUMP,LS 35$
	LOAD.W	D3,#MAXIRAQ
35$:
	NEG.W	D3		; D3 <-- inclinaison choisie

	CALL	MOVERAQ		; dplace la raquette du SMAKY
	COMP.W	D0,(A4)+ORAQPO+2
	JUMP,NE	31$

	LOAD.L	A5,#(A6)+OBALLE
	CALL	INVOBJ
	SUB.W	(A5)+OOBPOS+0,#RAQEL ; lve la balle
	CALL	INVOBJ

; Lance la balle servie par le joueur ou le SMAKY.

38$:
	LOAD.L	A3,#R16"TMUSSERVICE
	CALL	PATATRA		; banza, c'est parti !

	CALL	ESERVICE	; efface les indicateurs de service

	LOAD.L	A3,#R16"TXMENU2
	LIB	?AFMENU		; affiche les soft-keys

	CALL	MAJOBJET	; A5 <-- met  jour l'objet
	TCLR.B	(A4)+ORAQET:#BRAQS ; fin du service

; Joue avec la balle jusqu' ce qu'elle tombe.

	CLR.B	(A6)+OBEGIN
	CLR.B	(A6)+OEND
	CLR.B	(A6)+OHELP
40$:
	CALL	BEGINTIME	; enregistre le temps systme absolu
41$:
	TEST.B	(A6)+OHELP	; appel  l'aide ?
	JUMP,T	AIDE

	TEST.B	(A6)+OEND	; fin de la partie ?
	JUMP,T	FINI

	LOAD.L	A5,#(A6)+OBALLE
	TEST.B	(A5)+OOBOLD	; objet mort ?
	JUMP,T	50$		; oui => 50$

	CALL	ACTION		; effectue une action ...
	JUMP,NE 45$		; si pas d'action effectue => 45$
	CALL	DELTATIME	; D4 <-- temps coul
	COMP.W	D4,(A6)+OTIMING
	JUMP,LO 41$
45$:
	LOAD.L	A5,#(A6)+OBALLE
	CALL	SMAKY		; dplace la raquette du SMAKY
	CALL	MOVEOBJ		; dplace la balle
	CALL	VIEBRIQUE	; volution des briques dtruites
	CALL	VIECOMPTE	; clignottement des compteurs
	JUMP	40$

; La balle est casse. Le joueur ou le SMAKY a gagn.

50$:
	LOAD.W	D4,#20
51$:
	CALL	ACTION		; attend encore un peu ...
	LOAD.L	A5,#(A6)+OBALLE
	CALL	SMAKY		; dplace la raquette du SMAKY
	CALL	MOVEOBJ		; dplace la balle
	CALL	VIEBRIQUE	; volution des briques dtruites
	CALL	VIECOMPTE	; clignottement des compteurs

	DEC.W	D4
	JUMP,NE 51$

	CALL	INVOBJ		; efface le rsidu de balle casse

	INC.W	(A6)+OCONJ
	TEST.B	(A6)+OGAGNE
	JUMP,T	60$
	DEC.W	(A6)+OCONJ
	INC.W	(A6)+OCONS
60$:
	LOAD.W	D4,(A6)+OCONJ
	SUB.W	D4,(A6)+OCONS
	JUMP,NC 62$
	NEG.W	D4		; D4 <-- |cart|
62$:
	COMP.W	D4,#2		; au moins 2 points d'cart ?
	JUMP,LO NEWBALLE	; non => joue encore

	COMP.W	(A6)+OCONJ,#MAXPOINT ; est-ce que le joueur a gagn ?
	JUMP,HS 70$
	COMP.W	(A6)+OCONS,#MAXPOINT ; est-ce que le SMAKY a gagn ?
	JUMP,HS 70$
	JUMP	NEWBALLE

70$:
	CALL	GAGNE		; affiche gagn/perdu ...
	COMP.W	D3,#F0
	JUMP,EQ FINI
	JUMP	NEWPARTIE



; Fin de ce (trs) joli jeu. Libre la mmoire pour SMILE !

FINI:
	TEST.L	(A6)+OPIMA
	JUMP,EQ 20$
	LOAD.L	A4,(A6)+OPIMA
	CALL	KILLIMAGE	; libre l'image
20$:
	LOAD.L	A4,A6
	LOAD.W	D1,#MTYPCP
	GESMEM	?GIVMEM		; libre la mmoire des variables

ERFAT:
	LIB	?AFTIM
	.B	AFSCMO		; remet la flche-souris
	.B	KILLGC		; libre les icnes IPP64
	.B	GCICF
	.B	GCICS
	.B	GCICT
	.B	0
	.EVEN

	.IF	~IFSMILE
	LIB	?CLOLIB
	FOS	?STOP
	.ELSE
	EXIT
	.ENDIF




;--------\\
; GAGNE   >
;========/

; Affiche "gagn ..."

; in	-
; out	D3.W	dernire touche presse (F0/F1)
; mod	D3.L, D7.W

GAGNE:
	PUSHM.L	D0..D2,D4,A3

	LOAD.L	A3,#R16"TXMENU1
	LIB	?AFMENU		; affiche les soft-keys

	LOAD.L	A3,#R16"NFIMA
	LOAD.W	D3,#F0
	CALL	AFIMAGE		; affiche l'image de fin
	JUMP,NE 90$

	LOAD.L	A3,#R16"01$
	CLR.W	D0		; D0 <-- c'est le joueur qui a gagn
	CLR.L	D3
	LOAD.W	D3,(A6)+OCONJ
	SUB.W	D3,(A6)+OCONS
	JUMP,NC 03$
	NEG.W	D3
	INC.W	D0		; D0 <-- c'est le SMAKY qui a gagn
	LOAD.L	A3,#R16"02$
03$:
	DIV.WU	D3,#4
	COMP.W	D3,#3
	JUMP,LS 04$
	LOAD.W	D3,#3
04$:
	DEC.W	D3
	JUMP,NS 08$
06$:
	TEST.B	(A3+)		; A3 <-- ^le bon texte
	JUMP,NE 06$
	JUMP	04$
08$:
	TEST.B	(A6)+OINV	; fond de l'cran blanc ?
	JUMP,F	10$		; non => 10$
	LOAD.B	D3,#AFINV	; oui =>
	LIB	?AFCAR		; affiche un inverse vido
10$:
	LOAD.L	D4,#H'10000*(LYWDO-242)+306
11$:
	LOAD.L	D3,D4
	LIB	?SETCURS	; met le curseur au dbut de la ligne
12$:
	LOAD.B	D3,(A3+)
	JUMP,EQ 16$
	COMP.B	D3,#CR
	JUMP,EQ 14$
	LIB	?AFCAR		; affiche une ligne
	JUMP	12$
14$:
	SWAP.W	D4
	ADD.W	D4,(A0)+ODFCY	; D4 <-- position ligne en dessous
	SWAP.W	D4
	JUMP	11$

16$:
	LOAD.L	A3,#R16"TMUSYOUPIE
	TEST.W	D0
	JUMP,EQ 17$
	LOAD.L	A3,#R16"TMUSPERDU
17$:
	CALL	PATATRA		; jolie/vilaine musique

20$:
	LIB	?GETCAR		; attend clavier/souris ...

	LOAD.W	D2,#F0		; D2 <-- F0
	COMP.W	D3,#F0
	JUMP,EQ 60$
	COMP.W	D3,#F0+SHIFT
	JUMP,EQ 60$
	COMP.W	D3,#END
	JUMP,EQ 60$

	LOAD.W	D2,#F1		; D2 <-- F1
	COMP.W	D3,#F1
	JUMP,EQ 60$
	COMP.W	D3,#F1+SHIFT
	JUMP,EQ 60$
	COMP.W	D3,#F2
	JUMP,EQ 60$
	COMP.W	D3,#F2+SHIFT
	JUMP,EQ 60$
	COMP.W	D3,#F3
	JUMP,EQ 60$
	COMP.W	D3,#F3+SHIFT
	JUMP,EQ 60$

	COMP.W	D3,#KEYMGR
	JUMP,EQ 20$
	COMP.W	D3,#KEYMMR
	JUMP,EQ 20$
	COMP.W	D3,#KEYMDR
	JUMP,EQ 20$
30$:				; petit bruit =>
	LOAD.B	D3,#BIPLIT
	LIB	?BEEP
	JUMP	20$

60$:
	LOAD.W	D3,D2		; D3 <-- dernire touche
90$:
	LIB	?AFTIM
	.B	AFDIR,0		; remet la vido normale
	.EVEN

	POPM.L	D0..D2,D4,A3
	RET

01$:
	.ASCII	"  BRAVO, vous avez battu<CR>"
	.ASCII	"  le SMAKY, mais c'tait<CR>"
	.ASCII	"  de peu ...<CR>"
	.ASCIZ	"  C'EST BIEN !"
		;                             ;
	.ASCII	"  BRAVO, vous avez gagn<CR>"
	.ASCII	"  contre le SMAKY haut la<CR>"
	.ASCII	"  main.<CR>"
	.ASCIZ	"  C'EST TRES BIEN !!"
		;                             ;
	.ASCII	"  BRAVO, vous avez largement<CR>"
	.ASCII	"  vaincu le SMAKY.<CR>"
	.ASCII	"<CR>"
	.ASCIZ	"  CHAMPION !!!"
		;                             ;
	.ASCII	" BRAVO, vous avez ridiculis<CR>"
	.ASCII	" votre adversaire (le SMAKY).<CR>"
	.ASCII	"<CR>"
	.ASCIZ	" SUPER-CHAMPION !!!"
		;                             ;

02$:
	.ASCII	" DESOLE, mais le SMAKY vous<CR>"
	.ASCII	" a battu (de peu c'est vrai).<CR>"
	.ASCII	"<CR>"
	.ASCIZ	" RECOMMENCEZ ..."
		;                             ;
	.ASCII	" DESOLE, mais c'est le SMAKY<CR>"
	.ASCII	" qui a gagn cette partie !<CR>"
	.ASCII	"<CR>"
	.ASCIZ	" ESSAYEZ ENCORE UNE FOIS ..."
		;                             ;
	.ASCII	" DESOLE, mais le SMAKY vous<CR>"
	.ASCII	" a largement battu !<CR>"
	.ASCII	" Il reste beaucoup de progrs<CR>"
	.ASCIZ	"  faire ..."
		;                             ;
	.ASCII	" DESOLE, mais le SMAKY vous<CR>"
	.ASCII	" a littralement aplati !<CR>"
	.ASCII	" Recommencez si vous tes<CR>"
	.ASCIZ	" trs courrageux ... "
		;                             ;


	.EVEN


;--------\\
; ACTION  >
;========/

; Agit selon un vnement clavier/souris.

; in	-
; out	D7.W	EQ => action effectue
;		NE => pas d'action (timeout)
; mod	D7.W

ACTION:
	PUSHM.L	D0..D6,A0..A5

	LOAD.L	A4,#(A6)+ORAQJ	; A4 <-- description raquette joueur

	LOAD.W	D4,(A6)+OTIMING
	NTREL	?SETTIM		; met timeout pour 25 images/seconde
	LIB	?GETKEY		; attend clavier/souris ...
	LOAD.W	D0,D7
	LOAD.W	D4,#-1
	NTREL	?SETTIM		; remet timeout infini
	TEST.W	D0
	JUMP,NE MOREPEAT

	TEST.L	D3:#BKPSEUDO
	JUMP,BC 20$
	TEST.L	D3:#BKRELEAS
	JUMP,BC ENDACTION
				; touche relche =>
	SWAP.W	D3
	AND.B	D3,#H'7F	; D3 <-- pseudo code (toujours majuscule)

	COMP.B	D3,#'E
	JUMP,EQ MORIGHTR
	COMP.B	D3,#'T
	JUMP,EQ MOLEFTR

	COMP.W	D3,#'S
	JUMP,EQ KEYLEFTR
	COMP.W	D3,#'D
	JUMP,EQ KEYLEFTR
	COMP.W	D3,#'G
	JUMP,EQ KEYRIGHTR
	COMP.W	D3,#'F
	JUMP,EQ KEYRIGHTR
	JUMP	ENDACTION

20$:				; touche presse =>
	COMP.W	D3,#'E
	JUMP,EQ MORIGHTP
	COMP.W	D3,#'e
	JUMP,EQ MORIGHTP
	COMP.W	D3,#'T
	JUMP,EQ MOLEFTP
	COMP.W	D3,#'t
	JUMP,EQ MOLEFTP

	COMP.W	D3,#'S
	JUMP,EQ KEYLEFTP
	COMP.W	D3,#'s
	JUMP,EQ KEYLEFTP
	COMP.W	D3,#'D
	JUMP,EQ KEYLEFTP
	COMP.W	D3,#'d
	JUMP,EQ KEYLEFTP
	COMP.W	D3,#'G
	JUMP,EQ KEYRIGHTP
	COMP.W	D3,#'g
	JUMP,EQ KEYRIGHTP
	COMP.W	D3,#'F
	JUMP,EQ KEYRIGHTP
	COMP.W	D3,#'f
	JUMP,EQ KEYRIGHTP

	COMP.W	D3,#KEYMPO
	JUMP,EQ MOMOVE
	COMP.W	D3,#KEYMDP
	JUMP,EQ MOLEFTP
	COMP.W	D3,#KEYMDR
	JUMP,EQ MOLEFTR
	COMP.W	D3,#KEYMGP
	JUMP,EQ MORIGHTP
	COMP.W	D3,#KEYMGR
	JUMP,EQ MORIGHTR

	COMP.W	D3,#END
	JUMP,EQ DOEND
	COMP.W	D3,#F0
	JUMP,EQ DOEND
	COMP.W	D3,#F0+SHIFT
	JUMP,EQ DOEND

	COMP.W	D3,#F1
	JUMP,EQ DOBEGIN
	COMP.W	D3,#F1+SHIFT
	JUMP,EQ DOBEGIN
	COMP.W	D3,#F2
	JUMP,EQ DOBEGIN
	COMP.W	D3,#F2+SHIFT
	JUMP,EQ DOBEGIN
	COMP.W	D3,#F3
	JUMP,EQ DOBEGIN
	COMP.W	D3,#F3+SHIFT
	JUMP,EQ DOBEGIN
	COMP.W	D3,#SPACE
	JUMP,EQ DOBEGIN
	COMP.W	D3,#KEYMMP
	JUMP,EQ DOBEGIN1
	COMP.W	D3,#'R
	JUMP,EQ DOBEGIN1
	COMP.W	D3,#'r
	JUMP,EQ DOBEGIN1

	COMP.W	D3,#F13
	JUMP,EQ DOHELP
	COMP.W	D3,#F13+SHIFT
	JUMP,EQ DOHELP
	COMP.W	D3,#F14
	JUMP,EQ DOHELP
	COMP.W	D3,#F14+SHIFT
	JUMP,EQ DOHELP
	COMP.W	D3,#F15
	JUMP,EQ DOHELP
	COMP.W	D3,#F15+SHIFT
	JUMP,EQ DOHELP
	COMP.W	D3,#HELP
	JUMP,EQ DOHELP

	JUMP	ENDACTION



MOREPEAT:			; rpte ventuellement qq chose =>
	TEST.B	(A4)+ORAQET:#BRAQL
	JUMP,BS MOLEFTP
	TEST.B	(A4)+ORAQET:#BRAQR
	JUMP,BS MORIGHTP

	TEST.B	(A4)+ORAQET:#BRAQG
	JUMP,BS KEYLEFTP
	TEST.B	(A4)+ORAQET:#BRAQD
	JUMP,BS KEYRIGHTP

;;?	TEST.W	(A4)+ORAQEL	; raquette leve ?
;;?	JUMP,EQ ENDACTION	; non => ENDACTION
	LOAD.L	D4,(A4)+ORAQPO	; D4 <-- position
	LOAD.W	D3,(A4)+ORAQIN	; D3 <-- inclinaison
	CALL	MOVERAQ		; dplace la raquette
	JUMP	ENDACTION

MOMOVE:				; souris dplace =>
	CALL	IFMOUSE		; D4 <-- position de la souris
	JUMP,NE ENDACTION
MOMOVE1:
	LOAD.L	D3,D4
	SWAP.W	D3
	SUB.W	D3,#POSYRAQ	; brusque dplacement contre le haut ?
	JUMP,HS 40$		; non => 40$
	COMP.W	D3,#-10		; assez brusque ?
	JUMP,GT 40$		; non => 40$
	LOAD.W	(A4)+ORAQEL,#RAQEL ; lve brusquement la raquette
40$:
	LOAD.W	D3,(A4)+ORAQIN	; D3 <-- inclinaison
	CALL	MOVERAQ		; dplace la raquette
	LOAD.L	D4,(A4)+ORAQPO
	CALL	PMOUSE		; met la souris o est la raquette !
	JUMP	MOREPEAT


MOLEFTP:			; [GAUCHE] press =>
	TSET.B	(A4)+ORAQET:#BRAQL
	LOAD.L	D4,(A4)+ORAQPO
	LOAD.W	D3,(A4)+ORAQIN
	ADD.W	D3,#+1
	COMP.W	D3,#+MAXIRAQ
	JUMP,LT 50$
	LOAD.W	D3,#+MAXIRAQ
	TCLR.B	(A4)+ORAQET:#BRAQL
50$:
	CALL	MOVERAQ		; dplace la raquette
	JUMP	ENDACTION

MOLEFTR:			; [GAUCHE] relch =>
	TCLR.B	(A4)+ORAQET:#BRAQL
	JUMP	ENDACTION

MORIGHTP:			; [DROITE] press =>
	TSET.B	(A4)+ORAQET:#BRAQR
	LOAD.L	D4,(A4)+ORAQPO
	LOAD.W	D3,(A4)+ORAQIN
	ADD.W	D3,#-1
	COMP.W	D3,#-MAXIRAQ
	JUMP,GT 50$
	LOAD.W	D3,#-MAXIRAQ
	TCLR.B	(A4)+ORAQET:#BRAQR
50$:
	CALL	MOVERAQ		; dplace la raquette
	JUMP	ENDACTION

MORIGHTR:			; [DROITE] relch =>
	TCLR.B	(A4)+ORAQET:#BRAQR
	JUMP	ENDACTION


KEYLEFTP:
	TSET.B	(A4)+ORAQET:#BRAQG

	LOAD.L	D4,(A4)+ORAQPO
	ADD.W	D4,#-10
	LOAD.W	D3,(A4)+ORAQIN	; D3 <-- inclinaison
	CALL	MOVERAQ		; dplace la raquette
	LOAD.L	D4,(A4)+ORAQPO
	CALL	PMOUSE		; met la souris o est la raquette !
	JUMP	ENDACTION

KEYLEFTR:
	TCLR.B	(A4)+ORAQET:#BRAQG
	JUMP	ENDACTION

KEYRIGHTP:
	TSET.B	(A4)+ORAQET:#BRAQD

	LOAD.L	D4,(A4)+ORAQPO
	ADD.W	D4,#+10
	LOAD.W	D3,(A4)+ORAQIN	; D3 <-- inclinaison
	CALL	MOVERAQ		; dplace la raquette
	LOAD.L	D4,(A4)+ORAQPO
	CALL	PMOUSE		; met la souris o est la raquette !
	JUMP	ENDACTION

KEYRIGHTR:
	TCLR.B	(A4)+ORAQET:#BRAQD
	JUMP	ENDACTION


DOEND:
	SET.B	(A6)+OEND	; signal la fin de la partie
	JUMP	ENDACTION

DOBEGIN:
	LOAD.W	(A4)+ORAQEL,#RAQEL ; lve brusquement la raquette
	SET.B	(A6)+OBEGIN	; signal le dbut de la partie
	JUMP	ENDACTION

DOBEGIN1:
	LOAD.W	(A4)+ORAQEL,#RAQEL ; lve brusquement la raquette
	TEST.B	(A6)+OFIXE	; raquette fixe ?
	JUMP,T	ENDACTION	; oui => ENDACTION
	SET.B	(A6)+OBEGIN	; non => signal le dbut de la partie
	JUMP	ENDACTION

DOHELP:
	SET.B	(A6)+OHELP	; signal un appel  l'aide
	SET.B	(A6)+OEND	; signal la fin de la partie
	JUMP	ENDACTION

ENDACTION:
	LOAD.W	D7,D0		; D7 <-- action ou pas

	POPM.L	D0..D6,A0..A5
	TEST.W	D7		; retour EQ/NE
	RET


;--------\\
; SMAKY   >
;========/

; Dplace la raquette du SMAKY.

; in	A5.L	^description de l'objet
; out	-
; mod	D7.W

SMAKY:
	PUSHM.L	D0..D4,A4

	LOAD.L	A4,#(A6)+ORAQS	; A4 <-- ^description raquette SMAKY

	COMP.W	(A5)+OOBPOS+2,#FRONTX
	JUMP,HS 20$

; Si la balle est dans le camp du joueur, adopte une stratgie
; dfensive (raquette au fond), d'attaque (raquette au filet)
; ou collante (suiveuse) de faon alatoire.

	TEST.B	(A6)+OSTRAT:#1
	JUMP,BS 15$
				; stratgie suiveuse =>
	LOAD.W	D4,(A6)+ORAQJ+ORAQFX
	SUB.W	D4,(A6)+ORAQJ+ORAQPO+2
	ADD.W	D4,(A4)+ORAQDX	; D4 <-- miroir de la raquette du joueur
	JUMP	40$
15$:
	LOAD.W	D4,(A4)+ORAQDX	; D4 <-- raquette au filet
	TEST.B	(A6)+OSTRAT:#2
	JUMP,BS 40$
	LOAD.W	D4,(A4)+ORAQFX	; D4 <-- raquette au fond
	JUMP	40$

20$:
	TEST.W	(A5)+OOBVIT+0	; balle monte ?
	JUMP,NS 30$		; oui => 30$

; Si la balle descend, calcul une estimation linaire du point
; de chute de la balle.

	LOAD.L	D1,(A5)+OOBPOO	; D1 <-- position balle  t-1
	LOAD.L	D2,(A5)+OOBPOS	; D2 <-- position balle  t

	LOAD.L	D3,(A5)+OOBDIM
	SR.W	D3,#1
	ADD.W	D1,D3
	ADD.W	D2,D3
	SWAP.W	D1
	SWAP.W	D2
	SWAP.W	D3
	SR.W	D3,#1
	ADD.W	D1,D3
	ADD.W	D2,D3
	SWAP.W	D1
	SWAP.W	D2
;	SWAP.W	D3

	LOAD.W	D3,#POSYRAQ+22
	LOAD.W	D4,D3
	SWAP.W	D3
	SWAP.W	D4
	LOAD.W	D3,#IDXRAQ
	LOAD.W	D4,#10000
	CALL	GAINTERHV	; D0 <-- point d'intersection P1-P2 et P3-P4
	JUMP,NE 90$

	LOAD.W	D4,D0
	SUB.W	D4,#IDXRAQ/2
	JUMP	40$

; Si la balle monte, met la raquette juste dessous.

30$:
	LOAD.W	D4,(A5)+OOBPOS+2
	LOAD.W	D3,(A5)+OOBDIM+2
	SR.W	D3,#1
	ADD.W	D4,D3
	SUB.W	D4,#IDXRAQ/2

; Avance ou recule sur le point de chute prsum, mais sans
; dpasser une vitesse maximale.

40$:
	COMP.W	D4,(A4)+ORAQPO+2
	JUMP,EQ 60$
	JUMP,LO 50$
				; avance vers la droite =>
	LOAD.W	D2,(A4)+ORAQPO+2
	ADD.W	D2,#MAXVITS
	COMP.W	D4,D2
	JUMP,LS 60$
	LOAD.W	D4,D2
	JUMP	60$
50$:				; avance vers la gauche =>
	LOAD.W	D2,(A4)+ORAQPO+2
	SUB.W	D2,#MAXVITS
	COMP.W	D4,D2
	JUMP,HS 60$
	LOAD.W	D4,D2
60$:
	CALL	SIMRAQIN	; D3 <-- inclinaison de la raquette
	CALL	MOVERAQ		; dplace la raquette du SMAKY
90$:
	POPM.L	D0..D4,A4
	RET

;---------\\
; SIMRAQIN >
;---------/

; Cherche la meilleure inclinaison pour la raquette du SMAKY.
; Cette routine contient en quelque sorte la "stratgie" de
; jeu du SMAKY !

; in	A5.L	^description de l'objet
;	A4.L	^description de la raquette
; out	D3.W	inclinaison de la raquette du SMAKY
; mod	D3.L, D7.W

SIMRAQIN:
	PUSHM.L	D2,D4

; Si la balle touche la raquette et qu'il reste beaucoup de
; briques, smash systmatique !
; S'il reste peu de briques, ne smash que si la balle ne va
; vraiment pas assez vite.

	CLR.W	D2		; D2 <-- pas de smash

	TEST.W	(A5)+OOBVIT+0	; balle descend ?
	JUMP,NS 20$		; non => 20$

	COMP.W	(A6)+OBRINB,#MAXBRI/2 ; reste beaucoup de briques ?
	JUMP,HS 10$		; oui => 10$

	COMP.W	(A5)+OOBVIT+0,#15 ; balle descend rapidement ?
	JUMP,HS 20$		; oui => 20$
10$:
	COMP.W	(A5)+OOBVIT+0,#MAXVITY-2 ; balle descend trs rapidement ?
	JUMP,HS 20$		; oui => 20$

	LOAD.L	D3,(A4)+ORAQPO
	LOAD.L	D4,#H'10000*IDYRAQ+IDXRAQ
	CALL	DETOBJ		; est-ce que la balle arrive sur la raquette ?
	JUMP,EQ 20$		; non => 20$
				; oui =>
	INC.W	D2		; D2 <-- smash
	LOAD.W	(A4)+ORAQEL,#RAQEL ; lve brusquement la raquette

; Calcul une inclinaison qui tient compte de la position
; de la raquette. Plus elle est  droite et plus elle
; est incline.

20$:
	LOAD.W	D3,(A4)+ORAQPO+2
	SUB.W	D3,(A4)+ORAQDX
	MUL.WU	D3,#MAXIRAQ

	LOAD.W	D4,(A4)+ORAQFX
	SUB.W	D4,(A4)+ORAQDX
	DIV.WU	D3,D4

; Plus la balle avance vite (Vx), plus il faut incliner la
; raquette.

	CLR.L	D4
	LOAD.W	D4,(A5)+OOBVIT+2
	JUMP,NS 30$
	DIV.WU	D4,#3
	ADD.W	D3,D4
30$:
	TEST.W	D2		; smash ?
	JUMP,EQ 70$		; non => 70$
				; oui =>
	ADD.W	D3,#4		; D3 <-- incline plus la raquette

; Si la raquette est trop incline, il faut la ramener dans
; une position possible !

70$:
	COMP.W	D3,#MAXIRAQ	; trop inclin ?
	JUMP,LS 75$
	LOAD.W	D3,#MAXIRAQ
75$:
	TEST.W	D3		; raquette horizontale ?
	JUMP,NE 80$
	INC.W	D3
80$:
	NEG.W	D3

	POPM.L	D2,D4
	RET




;----------\\
; BEGINTIME >
;==========/

; Mmorise le temps actuel.

; in	-
; out	-
; mod	D7.W

BEGINTIME:
	PUSHM.L	D2..D5

	NTREL	?GETSYTIME
	LOAD.L	(A6)+OTIME,D4	; OTIME <-- temps processeur total

	POPM.L	D2..D5
	RET

;----------\\
; DELTATIME >
;==========/

; Donne l'cart entre l'appel BEGINTIME et cet appel-l.

; in	-
; out	D4.W	cart (unit 20ms)
; mod	D4.L, D7.W

DELTATIME:
	PUSHM.L	D2,D3,D5

	NTREL	?GETSYTIME	; D4 <-- temps processeur total
	SUB.L	D4,(A6)+OTIME	; D4 <-- temps coul (unit 128us)
	DIV.WU	D4,#20000/128	; D4 <-- temps coul (unit 20ms)

	POPM.L	D2,D3,D5
	RET




;----------\\
; VIEBRIQUE >
;==========/

; Anime les briques dtruites.

; in	-
; out	-
; mod	D7.W

VIEBRIQUE:
	PUSHM.L	D2..D4,A4

	CLR.W	D4		; D4 <-- rang initial
20$:
	CALL	PETBRIQUE	; A4 <-- ^tat de la brique
	LOAD.B	D3,(A4)+0	; D3 <-- tat de la brique
	JUMP,EQ 50$
	COMP.B	D3,#-1
	JUMP,EQ 50$

	DEC.B	D3
	LOAD.B	(A4),D3

	SR.B	D3,#1
	JUMP,CS 50$
	SUB.B	D3,#NBABRI
	NEG.B	D3
	ADD.B	D3,(A4)+1	; D3 <-- code de l'icne
	LOAD.W	D2,#INVDOT
	CALL	DESBRIQUE	; efface un bout de brique
50$:
	INC.W	D4		; D4 <-- rang suivant
	COMP.W	D4,#MAXBRI
	JUMP,LO 20$

	POPM.L	D2..D4,A4
	RET

;----------\\
; ALLBRIQUE >
;==========/

; Dessine toutes les briques.

; in	-
; out	-
; mod	D7.W

ALLBRIQUE:
	PUSHM.L	D2..D4,A3,A4

	LOAD.L	A3,#R16"00$	; A3 <-- ^notes de la gamme
	CLR.W	D4		; D4 <-- rang initial
20$:
	TEST.W	(A6)+OBRINB
	JUMP,EQ 30$
	DEC.W	(A6)+OBRINB
	JUMP	50$
30$:
	LOAD.B	D3,#ICOBRIQUE
	LOAD.W	D2,#SETDOT
	CALL	DESBRIQUE	; dessine une brique

	CALL	PETBRIQUE	; A4 <-- ^tat de la brique
	LOAD.B	(A4)+0,#-1

	PUSHM.L	D3..D6
	LOAD.W	D3,(A3)
	LOAD.W	D4,#SILENCE
	LOAD.W	D5,#SILENCE
	LOAD.W	D6,#H'100*10+0
	LIB	?ACCORD
	POPM.L	D3..D6

	PUSH.W	D4
	LOAD.W	D4,#50/10
	NTREL	?DELMS		; attend trs peu ...
	POP.W	D4
50$:
	ADD.L	A3,#2		; A3 <-- ^note suivante
	INC.W	D4		; D4 <-- rang suivant
	COMP.W	D4,#MAXBRI
	JUMP,LO 20$

	LOAD.W	(A6)+OBRINB,#MAXBRI

	POPM.L	D2..D4,A3,A4
	RET

00$:
	.W	NOTE+OCTAVE*5+SGDO
	.W	NOTE+OCTAVE*5+SGRE
	.W	NOTE+OCTAVE*5+SGMI
	.W	NOTE+OCTAVE*5+SGFA
	.W	NOTE+OCTAVE*5+SGSOL
	.W	NOTE+OCTAVE*5+SGLA
	.W	NOTE+OCTAVE*5+SGSI
	.W	NOTE+OCTAVE*6+SGDO

;----------\\
; DESBRIQUE >
;==========/

; Dessine une brique.

; in	D4.W	rang (0..n)
;	D3.B	code de l'icne
;	D2.W	mode
; out	-
; mod	D7.W

DESBRIQUE:
	PUSHM.L	D1..D5

	LOAD.B	D1,D3
	CALL	POSBRIQUE	; D3/D4 <-- position/dimensions
	LOAD.L	D5,D4		; D5 <-- dimensions
	LOAD.L	D4,D3		; D4 <-- position
	LOAD.B	D3,D1		; D3 <-- code de l'icne

	CALL	DRICONE

	POPM.L	D1..D5
	RET

;----------\\
; PETBRIQUE >
;----------/

; Donne le pointeur sur l'tat d'une brique.

; in	D4.W	rang (0..n)
; out	A4.L	^tat
; mod	D7.W, A4.L

PETBRIQUE:
	PUSH.L	D4

	LOAD.L	A4,#(A6)+OBRIQUE
	SL.W	D4,#1
	ADD.W	A4,D4

	POP.L	D4
	RET

;----------\\
; POSBRIQUE >
;----------/

; Calcul la position et les dimensions d'une brique.
; Rang:		n-1	brique tout en haut
;		0	brique tout en bas
;		-1	plus de brique (support)

; in	D4.W	rang (-1,0..n)
; out	D3.L	position (y;x)
;	D4.L	dimensions (dy;dx)
; mod	D3.L, D4.L, D7.W

POSBRIQUE:
	LOAD.W	D3,D4
	INC.W	D3
	MUL.WU	D3,#IDYBRI
	SUB.W	D3,#POSYBRI
	NEG.W	D3
	SWAP.W	D3
	LOAD.W	D3,#POSXBRI

	LOAD.L	D4,#H'10000*IDYBRI+IDXBRI
	RET





;---------\\
; NEWOBJET >
;=========/

; Initialise un nouvel objet.

; in	A5.L	^descripteur de l'objet
; out	-
; mod	D7.W

NEWOBJET:
	PUSHM.L	D3,D4

	LOAD.B	(A5)+OOBICO,#ICOBALLE1

	LOAD.W	(A5)+OOBDIM+2,#IDXBALLE1
	LOAD.W	(A5)+OOBDIM+0,#IDYBALLE1

	LOAD.W	(A5)+OOBPOS+2,#LXWDO/2

	LOAD.W	(A5)+OOBCHO+2,#3
	LOAD.W	(A5)+OOBCHO+0,#3
	LOAD.W	(A5)+OOBACC,#2

	LOAD.W	(A5)+OOBVIM,#-1	; balle immortelle (pour le temps)
	LOAD.W	(A5)+OOBVIE,(A5)+OOBVIM

	LOAD.W	(A5)+OOBMU1,#TMUSCOLB1-TMUS
	LOAD.W	(A5)+OOBMU2,#TMUSCOLR1-TMUS
	LOAD.W	(A5)+OOBMU3,#TMUSENDB1-TMUS

	CLR.W	(A5)+OOBFIN
	CLR.W	(A5)+OOBVIF
	SET.B	(A5)+OOBNEW	; nouvel objet
	CLR.B	(A5)+OOBOLD	; pas encore mort

	POPM.L	D3,D4
	RET

;---------\\
; MAJOBJET >
;=========/

; Met  jour un nouvel objet selon la raquette.

; in	A5.L	^descripteur de l'objet
;	A4.L	^description de la raquette
; out	-
; mod	D7.W

MAJOBJET:
	PUSHM.L	D3,D4,A3

	LOAD.W	D4,(A4)+ORAQIN
	ASL.W	D4,#1
	LOAD.W	(A5)+OOBVIT+2,D4

	LOAD.L	A3,#R16"00$
	LOAD.W	D3,(A6)+OBRINB	; D3 <-- nb de briques restantes
	SL.W	D3,#1
	ADD.W	A3,D3
	LOAD.W	(A5)+OOBVIT+0,(A3)

	POPM.L	D3,D4,A3
	RET

; Cette table donne la vitesse d'engagement (Vy) en fonction
; du nombre de briques restantes.

00$:
	.W	-7		; 0
	.W	-10		; 1
	.W	-12		; 2
	.W	-14		; 3
	.W	-16		; 4
	.W	-18		; 5
	.W	-20		; 6
	.W	-22		; 7
	.W	-23		; 8
	.W	-24		; 9
	.W	-25		; 10


;--------\\
; MOVEOBJ >
;========/

; Dplace un objet.

; in	A5.L	^descripteur de l'objet
; out	-
; mod	D7.W

MOVEOBJ:
	PUSHM.L	D2..D5,A4

	LOAD.L	(A5)+OOBPOO,(A5)+OOBPOS

	LOAD.L	D4,(A5)+OOBPOS	; D4 <-- position actuelle
	LOAD.L	D2,D4
	ADD.W	D4,(A5)+OOBVIT+2
	SWAP.W	D4
	ADD.W	D4,(A5)+OOBVIT+0
	SWAP.W	D4

	CALL	BORDOBJ		; choc (oh l) avec un bord ?
	COMP.W	(A5)+OOBVIE,#1	; objet presque mort ?
	JUMP,LS 30$		; oui => 30$

	CALL	BRIOBJ		; choc avec des briques ?

	LOAD.L	A4,#(A6)+ORAQJ	; A4 <-- ^description raquette joueur
	CALL	RAQOBJ		; choc avec la raquette du joueur ?

	LOAD.L	A4,#(A6)+ORAQS	; A4 <-- ^description raquette SMAKY
	CALL	RAQOBJ		; choc avec la raquette  du SMAKY ?
30$:
	TEST.W	(A5)+OOBVIE	; objet en vie ?
	JUMP,NE 40$		; oui => 40$
				; non =>
	LOAD.L	D4,D2		; D4 <-- ne le dplace plus du tout
40$:
	LOAD.L	D3,(A5)+OOBPOS	; D3 <-- ancienne position
	LOAD.L	D5,(A5)+OOBDIM	; D5 <-- dimensions
	CALL	MOVEIICONE	; dplace l'objet
	LOAD.L	(A5)+OOBPOS,D4	; mm. nouvelle position

	LOAD.W	D4,(A5)+OOBACC
	ADD.W	(A5)+OOBVIT+0,D4 ; tient compte de la pesanteur !
	CALL	MAXVIT		; ne va quand mme pas trop vite
90$:
	POPM.L	D2..D5,A4
	RET

;--------\\
; BORDOBJ >
;--------/

; Teste une collision avec un bord de la fentre.

; in	A5.L	^descripteur de l'objet
;	D4.L	position (y;x)
; out	D4.L	position (y;x)
; mod	D4.L, D7.W

BORDOBJ:
	PUSHM.L	D2,D3

	CLR.W	D2		; D2 <-- pas de collision
	SWAP.W	D4

; Teste une collision avec le sol.

	LOAD.W	D3,(A0)+ODFFDY
	SUB.W	D3,#MARGB
	SUB.W	D3,(A5)+OOBDIM+0
	COMP.W	D4,D3		; collision avec le sol ?
	JUMP,LT 20$
	LOAD.W	D4,D3

	COMP.W	D4,(A5)+OOBPOS+0
	JUMP,NE 14$
	DEC.W	D2		; D2 <-- ne fait pas de bruit !
14$:
	NEG.W	(A5)+OOBVIT+0	; inverse la vitesse Vy
	LOAD.W	D3,(A5)+OOBCHO+0
	CALL	UPVIT		; diminue la vitesse contre en haut

	INC.W	D2		; D2 <-- une collision

	TEST.W	(A5)+OOBVIE	; objet dj mort ?
	JUMP,EQ 20$		; oui => 20$
				; non =>
	LOAD.W	(A5)+OOBVIE,#1	; mort de l'objet !

	SWAP.W	D4
	COMP.W	D4,#FRONTX
	JUMP,LT 16$
				; c'est gagn =>
	SET.B	(A6)+OGAGNE
	LOAD.W	D3,#FRONTX+30
	COMP.W	D4,D3
	JUMP,HS 18$
	LOAD.W	D4,D3
	JUMP	18$
16$:				; c'est perdu =>
	SET.B	(A6)+OPERDU
	LOAD.W	D3,(A5)+OOBDIM+2
	SR.W	D3,#1
	NEG.W	D3
	ADD.W	D3,#FRONTX-32
	COMP.W	D4,D3
	JUMP,LS 18$
	LOAD.W	D4,D3
18$:
	SWAP.W	D4

; Teste une collision avec le plafond.

20$:
	LOAD.W	D3,#MARGH
	COMP.W	D4,D3		; collision avec le plafond ?
	JUMP,GT 30$
	LOAD.W	D4,D3

	COMP.W	D4,(A5)+OOBPOS+0
	JUMP,NE 24$
	DEC.W	D2		; D2 <-- ne fait pas de bruit !
24$:
	NEG.W	(A5)+OOBVIT+0	; inverse la vitesse Vy
	LOAD.W	D3,(A5)+OOBCHO+0
	CALL	DOWNVIT		; diminue la vitesse contre en bas

	INC.W	D2		; D2 <-- une collision

; Teste une collision avec le bord droite.

30$:
	SWAP.W	D4

	LOAD.W	D3,(A0)+ODFFDX
	SUB.W	D3,#MARGD
	SUB.W	D3,(A5)+OOBDIM+2
	COMP.W	D4,D3		; collision avec le bord droite ?
	JUMP,LT 40$
	LOAD.W	D4,D3

	COMP.W	D4,(A5)+OOBPOS+2
	JUMP,NE 34$
	DEC.W	D2		; D2 <-- ne fait pas de bruit !
34$:
	NEG.W	(A5)+OOBVIT+2	; inverse la vitesse Vx
	LOAD.W	D3,(A5)+OOBCHO+2
	CALL	LEFTVIT		; diminue la vitesse vers la gauche

	INC.W	D2		; D2 <-- une collision

; Teste une collision avec le bord gauche.

40$:
	LOAD.W	D3,#MARGG
	COMP.W	D4,D3		; collision avec le bord gauche ?
	JUMP,GT 50$
	LOAD.W	D4,D3

	COMP.W	D4,(A5)+OOBPOS+2
	JUMP,NE 44$
	DEC.W	D2		; D2 <-- ne fait pas de bruit !
44$:
	NEG.W	(A5)+OOBVIT+2	; inverse la vitesse Vx
	LOAD.W	D3,(A5)+OOBCHO+2
	CALL	RIGHTVIT	; diminue la vitesse vers la droite

	INC.W	D2		; D2 <-- une collision

; Fait un bruit en cas de collision.

50$:
	TEST.W	D2		; une collision ?
	JUMP,EQ 90$		; non => 90$
				; oui =>
	TEST.W	(A5)+OOBVIE	; objet en vie ?
	JUMP,EQ 90$		; non => 90$
				; oui =>
	CALL	MUS1OBJ		; bruit de collision avec un bord
90$:
	CALL	MAXVIT		; ne va quand mme pas trop vite

	POPM.L	D2,D3
	RET


;-------\\
; BRIOBJ >
;-------/

; Choc de la balles avec une ou plusieures briques.
; Supprime ventuellement la premire brique (tout en haut).

; in	A5.L	^description de l'objet
;	D4.L	position (y;x)
; out	D4.L	position (y;x)
; mod	D4.L, D7.W

BRIOBJ:
	PUSHM.L	D0..D3,D5,A3,A4

	LOAD.L	D5,D4		; D5 <-- nouvelle position

	LOAD.W	D4,(A6)+OBRINB
	DEC.W	D4		; D4 <-- rang de la brique tout en haut
	LOAD.W	D2,D4

	PUSH.L	(A5)+OOBPOS
	LOAD.L	(A5)+OOBPOS,D5
	PUSH.L	D4
	CALL	POSBRIQUE	; D3/D4 <-- position/dimensions
	CALL	DETOBJ		; collision avec la brique ?
	POP.L	D4
	POP.L	(A5)+OOBPOS
	TEST.W	D7
	JUMP,EQ 90$		; non => 90$
				; oui =>
	COMP.W	D2,#-1		; plus de briques ?
	JUMP,EQ 50$		; oui => 50$

	CALL	PETBRIQUE	; A4 <-- ^tat de la brique
	COMP.B	(A4)+0,#-1	; brique existe ?
	JUMP,NE 90$		; non => 90$
				; oui =>
	LOAD.B	(A4)+0,#NBABRI*2 ; enlve la brique
	LOAD.B	(A4)+1,#ICOBRIQUE

	DEC.W	(A6)+OBRINB	; une brique de moins
50$:
	CALL	COUPEBRIQUE	; rebond sur la brique

	LOAD.L	A3,#R16"TMUSCOLBRI1
	COMP.W	D2,#-1		; plus de briques ?
	JUMP,EQ 80$		; oui => 80$
	LOAD.L	A3,#R16"TMUSCOLBRI2
80$:
	CALL	PATATRA		; fait un bruit
90$:
	CALL	COUPEMUR	; collision avec le mur ?
	LOAD.L	D4,D5		; D4 <-- nouvelle position

	POPM.L	D0..D3,D5,A3,A4
	RET

;------------\\
; COUPEBRIQUE >
;------------/

; Regarde comment une balle coupe une brique, et simule
; un rebond correct sur les 4 faces possibles.

; in	A5.L	^description de l'objet
;	D5.L	nouvelle position de l'objet
;	D4.W	rang de la brique (-1,0..n)
; out	D5.L	nouvelle position de l'objet
; mod	D5.L, D7.W

COUPEBRIQUE:
	PUSHM.L	D0..D4,D6

	LOAD.L	D1,(A5)+OOBPOS	; D1 <-- position au temps t
	LOAD.L	D2,D5		; D2 <-- position au temps t+1

	CALL	POSBRIQUE	; D3/D4 <-- position/dimensions
	LOAD.L	D5,D3		; D5 <-- position brique
	LOAD.L	D6,D4		; D6 <-- dimensions brique

	LOAD.L	D4,(A5)+OOBDIM
	SUB.W	D5,D4
	ADD.W	D6,D4
	SWAP.W	D4
	SWAP.W	D5
	SWAP.W	D6
	SUB.W	D5,D4
	ADD.W	D6,D4
	SWAP.W	D5
	SWAP.W	D6

	LOAD.L	D3,D1
	LOAD.L	D4,D2
	SWAP.W	D3
	SWAP.W	D4
	COMP.W	D3,D4
	JUMP,EQ 40$		; trajectoire horizontale => 40$
	JUMP,HI 20$
				; la balle descend =>
	LOAD.L	D3,D5		; D3 <-- position brique
	LOAD.L	D4,D6		; D4 <-- dimensions brique
	ADD.W	D4,D3
	SWAP.W	D3
	SWAP.W	D4
	LOAD.W	D4,D3
	SWAP.W	D4
	SWAP.W	D3
	CALL	GAINTERHV
	JUMP,NE 40$
	LOAD.L	D2,D0

	TEST.W	(A5)+OOBVIT+0
	JUMP,NS 40$
	NEG.W	(A5)+OOBVIT+0	; inverse la vitesse Vy
	LOAD.W	D3,#1
	CALL	UPVIT		; diminue la vitesse contre le haut
	JUMP	40$

20$:				; la balle monte =>
	LOAD.L	D3,D5		; D3 <-- position brique
	LOAD.L	D4,D6		; D4 <-- dimensions brique
	ADD.W	D4,D3
	SWAP.W	D3
	SWAP.W	D4
	ADD.W	D3,D4
	LOAD.W	D4,D3
	SWAP.W	D4
	SWAP.W	D3
	CALL	GAINTERHV
	JUMP,NE 40$
	LOAD.L	D2,D0

	TEST.W	(A5)+OOBVIT+0
	JUMP,NC 40$
	NEG.W	(A5)+OOBVIT+0	; inverse la vitesse Vy
	LOAD.W	D3,#5
	CALL	DOWNVIT		; diminue la vitesse contre le bas
40$:
	COMP.W	D1,D2
	JUMP,EQ 90$		; trajectoire verticale => 90$
	JUMP,HI 60$
				; la balle va  droite =>
	LOAD.L	D3,D5		; D3 <-- position brique
	LOAD.L	D4,D6		; D4 <-- dimensions brique
	LOAD.W	D4,D3
	SWAP.W	D3
	SWAP.W	D4
	ADD.W	D4,D3
	SWAP.W	D4
	SWAP.W	D3
	CALL	GAINTERHV
	JUMP,NE 90$
	LOAD.L	D2,D0

	TEST.W	(A5)+OOBVIT+2
	JUMP,NS 90$
	NEG.W	(A5)+OOBVIT+2	; inverse la vitesse Vx
	LOAD.W	D3,#1
	CALL	LEFTVIT		; diminue la vitesse contre la gauche
	JUMP	90$

60$:				; la balle va  gauche =>
	LOAD.L	D3,D5		; D3 <-- position brique
	LOAD.L	D4,D6		; D4 <-- dimensions brique
	ADD.W	D3,D4
	LOAD.W	D4,D3
	SWAP.W	D3
	SWAP.W	D4
	ADD.W	D4,D3
	SWAP.W	D4
	SWAP.W	D3
	CALL	GAINTERHV
	JUMP,NE 90$
	LOAD.L	D2,D0

	TEST.W	(A5)+OOBVIT+2
	JUMP,NC 90$
	NEG.W	(A5)+OOBVIT+2	; inverse la vitesse Vx
	LOAD.W	D3,#1
	CALL	RIGHTVIT	; diminue la vitesse contre la droite
90$:
	CALL	MAXVIT		; ne va quand mme pas trop vite

	LOAD.L	D5,D2		; D5 <-- nouvelle position

	POPM.L	D0..D4,D6
	RET

;---------\\
; COUPEMUR >
;---------/

; Regarde comment une balle coupe le mur constitu de toutes
; les briques, sauf celle tout en haut.

; in	A5.L	^description de l'objet
;	D5.L	nouvelle position de l'objet
; out	D5.L	nouvelle position de l'objet
; mod	D5.L, D7.W

COUPEMUR:
	PUSHM.L	D0..D4,D6,A3

	LOAD.L	D1,(A5)+OOBPOS	; D1 <-- position au temps t
	LOAD.L	D2,D5		; D2 <-- position au temps t+1

	LOAD.W	D4,(A6)+OBRINB
	SUB.W	D4,#2
	JUMP,LO 90$
	CALL	POSBRIQUE	; D3/D4 <-- position/dimensions
	SWAP.W	D3
	LOAD.W	D4,(A5)+OOBDIM+0
	SR.W	D4,#1
	SUB.W	D3,D4
	SWAP.W	D3
	LOAD.L	D5,D3
	LOAD.L	D6,D3
	SUB.W	D5,(A5)+OOBDIM+2 ; D5 <-- position mur gauche
	ADD.W	D6,#IDXBRI	; D6 <-- position mur droite

	COMP.W	D2,D5		; position au temps t+1 dans le mur ?
	JUMP,LO 90$		; non => 90$
	COMP.W	D2,D6
	JUMP,HS 90$
	LOAD.L	D3,D2
	SWAP.W	D3
	SWAP.W	D5
	COMP.W	D3,D5
	JUMP,LO 90$
	SWAP.W	D5

	COMP.W	D1,D2
	JUMP,EQ 90$		; trajectoire verticale => 90$
	JUMP,HI 60$
				; la balle va  droite =>
	LOAD.L	D3,D5		; D3 <-- position mur gauche
	LOAD.W	D4,#LYWDO
	SWAP.W	D4
	LOAD.W	D4,D3
	CALL	GAINTERHV
	JUMP,NE 90$
	LOAD.L	D2,D0
	SUB.W	D2,#2

	TEST.W	(A5)+OOBVIT+2
	JUMP,NS 80$
	NEG.W	(A5)+OOBVIT+2	; inverse la vitesse Vx
	LOAD.W	D3,#1
	CALL	LEFTVIT		; diminue la vitesse contre la gauche
	JUMP	80$

60$:				; la balle va  gauche =>
	LOAD.L	D3,D6		; D3 <-- position mur droite
	LOAD.W	D4,#LYWDO
	SWAP.W	D4
	LOAD.W	D4,D3
	CALL	GAINTERHV
	JUMP,NE 90$
	LOAD.L	D2,D0
	ADD.W	D2,#2

	TEST.W	(A5)+OOBVIT+2
	JUMP,NC 80$
	NEG.W	(A5)+OOBVIT+2	; inverse la vitesse Vx
	LOAD.W	D3,#1
	CALL	RIGHTVIT	; diminue la vitesse contre la droite
80$:
	LOAD.L	A3,#R16"TMUSCOLBRI1
	CALL	PATATRA		; fait un bruit
90$:
	CALL	MAXVIT		; ne va quand mme pas trop vite

	LOAD.L	D5,D2		; D5 <-- nouvelle position

	POPM.L	D0..D4,D6,A3
	RET


;--------\\
; RAQOBJ  >
;--------/

; Teste une collision avec la raquette.

; in	A5.L	^descripteur de l'objet
;	A4.L	^description de la raquette
;	D4.L	nouvelle position (y;x)
; out	D4.L	nouvelle position (y;x)
; mod	D4.L, D7.W

RAQOBJ:
	PUSHM.L	D0..D3,D5

	LOAD.L	D5,D4		; D5 <-- nouvelle position
	JUMP,EQ 90$
	TEST.L	(A5)+OOBPOS
	JUMP,EQ 90$
	TEST.L	(A4)+ORAQPO
	JUMP,EQ 90$

;;?	TEST.W	(A5)+OOBVIT+0	; est-ce que l'objet descend ?
;;?	JUMP,NS 90$		; non => 90$

	CALL	RAQDEDANS	; balle heurte la raquette ?
	JUMP,EQ 90$		; non => 90$

; Modifie la position pour tenir compte ( peu prt) du rebond.

	CALL	RAQDESSUS	; D4 <-- ramne dessus la raquette !

; Modifie la vitesse verticale.

	NEG.W	(A5)+OOBVIT+0	; inverse la vitesse Vy
	LOAD.W	D3,(A5)+OOBCHO+0
	SUB.W	D3,(A4)+ORAQEL	; D3 <-- tient compte de l'lvation de la raquette
	SUB.W	D3,(A4)+ORAQEL
	CALL	UPVIT		; diminue/augmente la vitesse contre le haut

; Modifie la vitesse horizontale.
; Lors d'un smash, Vy est augment seulement pour la raquette du joueur.
; Cel lui donne un petit avantage !

	CLR.W	D3
	COMP.B	(A4)+ORAQIC,#ICORAQS ; raquette du SMAKY ?
	JUMP,EQ 50$		; oui => 50$
	LOAD.W	D3,(A4)+ORAQEL
	JUMP,NC 50$
	NEG.W	D3
50$:
	LOAD.W	D4,(A4)+ORAQIN
	MUL.WA	D4,#3
	ADD.W	D4,D3
;;?	ADD.W	D4,D3
	ADD.W	(A5)+OOBVIT+2,D4

; Fait un bruit de collision avec la raquette.

	TEST.W	(A5)+OOBVIE	; objet en vie ?
	JUMP,EQ 90$		; non => 90$
				; oui =>
	LOAD.W	D3,(A5)+OOBVIT+0
	JUMP,NC 70$
	NEG.W	D3		; D3 <-- vitesse verticale absolue
70$:
	COMP.W	D3,#4		; petite vitesse ?
	JUMP,LO 90$		; oui => 90$
				; non =>
	CALL	MUS2OBJ		; bruit de collision avec la raquette
90$:
	CALL	MAXVIT		; ne va quand mme pas trop vite

	LOAD.L	D4,D5		; D4 <-- nouvelle position

	POPM.L	D0..D3,D5
	RET

;----------\\
; RAQDEDANS >
;----------/

; Regarde si la balle touche la raquette.

; in	D5.L	position de la balle
; out	D7.W	EQ => pas de collision avec la raquette
; mod	D7.W

RAQDEDANS:
	PUSHM.L	D3,D4

	PUSH.L	(A5)+OOBPOS
	LOAD.L	(A5)+OOBPOS,D5
	LOAD.L	D3,(A4)+ORAQPO
	SWAP.W	D3
	ADD.W	D3,#22
	SWAP.W	D3
	LOAD.L	D4,#H'10000*(IDYRAQ-22)+IDXRAQ
	CALL	DETOBJ		; nouvel objet dans la raquette ?
	POP.L	(A5)+OOBPOS

	POPM.L	D3,D4
	TEST.W	D7		; retour EQ/NE
	RET

;----------\\
; RAQDESSUS >
;----------/

; Remne la balle sur la raquette si par hazard elle est descendue
; en dessous !

; in	D5.L	position de la balle
; out	D5.L	position toujours dessus la raquette
; mod	D5.L, D7.W

RAQDESSUS:
	PUSHM.L	D0..D4

	CALL	RAQP1P2		; D1/D2 <-- points P1/P2 de la raquette

	LOAD.W	D0,(A5)+OOBDIM+2
	SR.W	D0,#1
	SUB.W	D1,D0
	SUB.W	D2,D0
	SWAP.W	D1
	SWAP.W	D2
	LOAD.W	D0,(A5)+OOBDIM+0
	SUB.W	D1,D0
	SUB.W	D2,D0
	SWAP.W	D1
	SWAP.W	D2

	LOAD.L	D3,D5
	LOAD.L	D4,D5
	SWAP.W	D3
	SUB.W	D3,#100
	SWAP.W	D3
	SWAP.W	D4
	ADD.W	D4,#100
	SWAP.W	D4

	CALL	GAINTERHV	; D0 <-- point d'intersection
	JUMP,NE 90$

	SWAP.W	D0
	SWAP.W	D5

	COMP.W	D5,D0		; en dessus de la raquette ?
	JUMP,LO 50$		; oui => 50$
	LOAD.W	D5,D0		; D4 <-- ramne dessus la raquette (en Y)
	SUB.W	D5,#2
50$:
	SWAP.W	D5
90$:
	POPM.L	D0..D4
	RET

;--------\\
; RAQP1P2 >
;--------/

; Donne les points P1(y,x) et P2(y,x) qui sont les extrmits
; gauche et droite de la raquette (variable selon l'inclinaison).

; in	A4.L	^description de la raquette
; out	D1.L	point P1(y,x)
;	D2.L	point P2(y,x)
; mod	D1.L, D2.L, D7.W

RAQP1P2:
	PUSHM.L	D3,A3

	LOAD.L	A3,#R16"TAIRAQ
	LOAD.W	D3,(A4)+ORAQIN
	NEG.W	D3
	ADD.W	D3,#MAXIRAQ
	SL.W	D3,#3		; D3 <-- *8 car table de 4x .W
	LOAD.L	D1,(A3)+(D3.W)+0 ; D1 <-- P1(y,x)
	LOAD.L	D2,(A3)+(D3.W)+4 ; D2 <-- P2(y,x)

	ADD.W	D1,(A4)+ORAQPO+2
	SWAP.W	D1
	SUB.W	D1,#IDYRAQ
	NEG.W	D1
	ADD.W	D1,(A4)+ORAQPO+0
	SWAP.W	D1

	ADD.W	D2,(A4)+ORAQPO+2
	SWAP.W	D2
	SUB.W	D2,#IDYRAQ
	NEG.W	D2
	ADD.W	D2,(A4)+ORAQPO+0
	SWAP.W	D2

	POPM.L	D3,A3
	RET

; Cette table donne les extrmits de la raquette, qui
; varie selon son inclinaison.

;		 P1      P2
;		 y,x     y,x
TAIRAQ:
	.W	62,13	18,57	; raquette \
	.W	59,10	21,60
	.W	56,07	24,62
	.W	55,06	27,63
	.W	52,03	31,62
	.W	49,03	34,63
	.W	46,01	37,62
	.W	41,00	41,63	; raquette -
	.W	07,01	45,63
	.W	34,01	48,61
	.W	31,02	51,60
	.W	28,01	54,58
	.W	25,02	56,56
	.W	22,04	59,53
	.W	18,06	62,50	; raquette /



;--------\\
; DOWNVIT >
;========/

; Diminue la vitesse de descente.

; in	A5.L	^descripteur de l'objet
;	D3.W	de combien diminuer
; out	-
; mod	D7.W

DOWNVIT:
	PUSH.L	D4

	LOAD.W	D4,(A5)+OOBVIT+0
	SUB.W	D4,D3
	JUMP,NC 20$
	CLR.W	D4
20$:
	LOAD.W	(A5)+OOBVIT+0,D4

	POP.L	D4
	RET

;--------\\
; UPVIT   >
;========/

; Diminue la vitesse de monte.

; in	A5.L	^descripteur de l'objet
;	D3.W	de combien diminuer
; out	-
; mod	D7.W

UPVIT:
	PUSH.L	D4

	LOAD.W	D4,(A5)+OOBVIT+0
	ADD.W	D4,D3
	JUMP,NS 20$
	CLR.W	D4
20$:
	LOAD.W	(A5)+OOBVIT+0,D4

	POP.L	D4
	RET

;---------\\
; RIGHTVIT >
;=========/

; Diminue la vitesse vers la droite.

; in	A5.L	^descripteur de l'objet
;	D3.W	de combien diminuer
; out	-
; mod	D7.W

RIGHTVIT:
	PUSH.L	D4

	LOAD.W	D4,(A5)+OOBVIT+2
	SUB.W	D4,D3
	JUMP,NC 20$
	CLR.W	D4
20$:
	LOAD.W	(A5)+OOBVIT+2,D4

	POP.L	D4
	RET

;--------\\
; LEFTVIT >
;========/

; Diminue la vitesse vers la gauche.

; in	A5.L	^descripteur de l'objet
;	D3.W	de combien diminuer
; out	-
; mod	D7.W

LEFTVIT:
	PUSH.L	D4

	LOAD.W	D4,(A5)+OOBVIT+2
	ADD.W	D4,D3
	JUMP,NS 20$
	CLR.W	D4
20$:
	LOAD.W	(A5)+OOBVIT+2,D4

	POP.L	D4
	RET


;--------\\
; MAXVIT  >
;========/

; Tronque les vitesses pour ne pas aller trop vite !

; in	A5.L	^description de l'objet
; out	-
; mod	D7.W

MAXVIT:
	PUSH.L	D4

	LOAD.W	D4,(A5)+OOBVIT+2
	COMP.W	D4,#-MAXVITX
	JUMP,GE 10$
	LOAD.W	D4,#-MAXVITX
10$:
	COMP.W	D4,#+MAXVITX
	JUMP,LE 15$
	LOAD.W	D4,#+MAXVITX
15$:
	LOAD.W	(A5)+OOBVIT+2,D4

	LOAD.W	D4,(A5)+OOBVIT+0
	COMP.W	D4,#-MAXVITY
	JUMP,GE 20$
	LOAD.W	D4,#-MAXVITY
20$:
	COMP.W	D4,#+MAXVITY
	JUMP,LE 25$
	LOAD.W	D4,#+MAXVITY
25$:
	LOAD.W	(A5)+OOBVIT+0,D4

	POP.L	D4
	RET


;--------\\
; MOVERAQ >
;========/

; Dplace la raquette.

; in	A4.L	^description de la raquette
;	D4.W	nouvelle position (x)
;	D3.W	nouvelle inclinaison (+/-)
; out	-
; mod	D7.W

MOVERAQ:
	PUSHM.L	D1..D5,A5

	TEST.B	(A6)+OMODE:#BFACILE	; mode facile ?
	JUMP,BC	02$			; non => 02$
	LOAD.W	D4,(A5)+OOBPOS+2
	LOAD.W	D2,(A5)+OOBDIM+2
	SR.W	D2,#1
	ADD.W	D4,D2
	SUB.W	D4,#IDXRAQ/2	; D4 <-- juste dessous la balle !
02$:
	TEST.B	(A6)+OFIXE	; raquette fixe ?
	JUMP,F	05$		; non => 05$
	LOAD.W	D4,#POSXRAQ	; D4 <-- impose la position horizontale
05$:
	TEST.W	(A4)+ORAQEL	; raquette leve ?
	JUMP,EQ 07$		; non => 07$
	DEC.W	(A4)+ORAQEL	; oui => rabaisse-la
07$:
	SWAP.W	D4
	LOAD.W	D4,#POSYRAQ	; D4 <-- impose la position verticale
	SUB.W	D4,(A4)+ORAQEL	; D4 <-- tient compte d'une ventuelle lvation
	SWAP.W	D4

; Regarde si la position ou l'inclinaison ont chang.
; Si l'un ou l'autre a chang, il faut redessiner la raquette.

	COMP.L	D4,(A4)+ORAQPO
	JUMP,NE 10$
	COMP.W	D3,(A4)+ORAQIN
	JUMP,EQ 90$
10$:
	LOAD.L	A5,#(A6)+OBALLE

; Vrifie si la position de la souris n'est ni trop  gauche
; ni trop  droite.

	LOAD.W	D2,(A4)+ORAQDX
	COMP.W	D4,D2		; souris trop  gauche ?
	JUMP,GE 25$
	LOAD.W	D4,D2
25$:
	LOAD.W	D2,(A4)+ORAQFX
	COMP.W	D4,D2		; souris trop  droite ?
	JUMP,LE 30$
	LOAD.W	D4,D2

; Regarde si l'ancienne ou la nouvelle raquette recoupe, mme
; partiellement, la balle.

30$:
	LOAD.W	D1,#1		; D1 <-- la balle recoupe la raquette
	TEST.B	(A4)+ORAQET:#BRAQS ; lancement de la balle ?
	JUMP,BS	35$		; oui => 35$

	PUSHM.L	D3,D4
	LOAD.L	D3,(A4)+ORAQPO
	LOAD.L	D4,#H'10000*IDYRAQ+IDXRAQ
	CALL	DETOBJ		; balle recoupe l'ancienne raquette ?
	LOAD.W	D1,D7		; D1 <-- zro si pas de collision
	POPM.L	D3,D4

	TEST.W	D1
	JUMP,NE 35$

	PUSHM.L	D3,D4
	LOAD.L	D3,D4
	LOAD.L	D4,#H'10000*IDYRAQ+IDXRAQ
	CALL	DETOBJ		; balle recoupe la nouvelle raquette ?
	LOAD.W	D1,D7		; D1 <-- zro si pas de collision
	POPM.L	D3,D4

; Dplace la raquette, en effaant puis en remettant la balle
; si elle recoupe l'ancienne ou la nouvelle raquette.

35$:
	TEST.W	D1
	JUMP,EQ 40$
	TEST.B	(A5)+OOBNEW
	JUMP,T	40$
	CALL	INVOBJ		; efface la balle

; Si on est en phase de lancement, met la balle sur la raquette,
; en tenant compte de son inclinaison.

40$:
	TEST.B	(A4)+ORAQET:#BRAQS
	JUMP,BC	50$

	LOAD.L	D5,D4
	ADD.W	D5,#IDXRAQ/2
	LOAD.W	D2,(A5)+OOBDIM+2
	SR.W	D2,#1
	SUB.W	D5,D2
	LOAD.W	D2,(A4)+ORAQIN
	ASR.W	D2,#1
	ADD.W	D5,D2
	SWAP.W	D5
	ADD.W	D5,#22
	SUB.W	D5,(A5)+OOBDIM+0
	LOAD.W	D2,(A4)+ORAQIN
	JUMP,NC 45$
	NEG.W	D2
45$:
	SR.W	D2,#1
	SUB.W	D5,D2
	SWAP.W	D5
	LOAD.L	(A5)+OOBPOS,D5	; met la balle sur la raquette

; Maintenant que la balle est ventuellement enleve, dplace
; l'icne de la raquette.

50$:
	LOAD.W	(A4)+ORAQIN,D3
	LOAD.W	D2,D3		; D2 <-- nouvelle inclinaison
	NEG.W	D2
	ADD.B	D2,(A4)+ORAQIC	; D2 <-- code de l'icne

	LOAD.L	D5,#H'10000*IDYRAQ+IDXRAQ ; D5 <-- dimensions
	LOAD.L	D3,(A4)+ORAQPO	; D3 <-- ancienne position
	CALL	MOVELICONE	; dplace l'icne
	LOAD.L	(A4)+ORAQPO,D4

; Remet la balle si elle avait t enleve.

	TEST.W	D1
	JUMP,EQ 90$
	CALL	INVOBJ		; remet la balle
	CLR.B	(A5)+OOBNEW
90$:
	POPM.L	D1..D5,A5
	RET

;--------\\
; DETOBJ  >
;========/

; Dtecte si un objet (rectangulaire) entre en collision
; avec une zone rectangulaire quelconque.

; in	A5.L	^description de l'objet
;	D3.L	coin sup/gauche (y;x)
;	D4.L	dimensions (dy;dx)
; out	D7.W	EQ => pas de collision
;		NE => collision
; mod	D7.W

DETOBJ:
	PUSHM.L	D2..D4

	CLR.W	D7		; D7 <-- pas de collision

	LOAD.W	D2,(A5)+OOBPOS+2
	ADD.W	D2,(A5)+OOBDIM+2
	COMP.W	D3,D2
	JUMP,HS 90$

	SUB.W	D2,(A5)+OOBDIM+2
	ADD.W	D3,D4
	COMP.W	D3,D2
	JUMP,LO 90$

	SWAP.W	D3
	SWAP.W	D4

	LOAD.W	D2,(A5)+OOBPOS+0
	ADD.W	D2,(A5)+OOBDIM+0
	COMP.W	D3,D2
	JUMP,HS 90$

	SUB.W	D2,(A5)+OOBDIM+0
	ADD.W	D3,D4
	COMP.W	D3,D2
	JUMP,LO 90$

	LOAD.W	D7,#1		; D7 <-- collision
90$:
	POPM.L	D2..D4
	TEST.W	D7		; retour EQ/NE
	RET

;--------\\
; INVOBJ  >
;========/

; Inverse un objet.

; in	A5.L	^descripteur de l'objet
; out	-
; mod	D7.W

INVOBJ:
	PUSHM.L	D2..D5

	CALL	GETICONE	; D2 <-- code de l'icne
	LOAD.B	D3,D2		; D3 <-- code de l'icne
	LOAD.W	D2,#INVDOT	; D2 <-- mode
	LOAD.L	D4,(A5)+OOBPOS	; D4 <-- position
	LOAD.L	D5,(A5)+OOBDIM	; D5 <-- dimensions
	CALL	DRICONE		; inverse l'icne

	POPM.L	D2..D5
	RET


;-----------\\
; MOVEIICONE >
;===========/

; Dplace une icne sur l'cran en l'inversant.

; in	A5.L	^description de l'objet
;	D3.L	ancienne position (y;x)
;	D4.L	nouvelle position (y;x)
;	D5.L	dimensions (dy;dx)
; out	-
; mod	D7.W

MOVEIICONE:
	PUSHM.L	D1..D4

	CALL	GETICONE	; D2 <-- code de l'ancienne icne
	LOAD.B	D1,D2		; D1 <-- code de l'ancienne icne
	CALL	AGEICONE	; vieilli l'icne !
	CALL	GETICONE	; D2 <-- code de la nouvelle icne

	COMP.L	D3,D4		; nouvelle position = ancienne ?
	JUMP,NE 20$
	COMP.B	D1,D2		; nouvelle icne = ancienne ?
	JUMP,EQ 90$		; oui => 90$
20$:
	PUSH.L	D3
	LOAD.B	D3,D2		; D3 <-- code de la nouvelle icne
	LOAD.W	D2,#INVDOT	; D2 <-- mode
	CALL	DRICONE		; dessine la nouvelle icne
	POP.L	D3

	TEST.B	(A5)+OOBNEW
	JUMP,T	80$
	LOAD.L	D4,D3		; D4 <-- ancienne position
	LOAD.B	D3,D1		; D3 <-- code de l'ancienne icne
	LOAD.W	D2,#INVDOT	; D2 <-- mode
	CALL	DRICONE		; efface l'ancienne icne
80$:
	CLR.B	(A5)+OOBNEW
90$:
	POPM.L	D1..D4
	RET

;---------\\
; GETICONE >
;=========/

; Donne le code de l'icne d'un objet.

; in	A5.L	^description de l'objet
; out	D2.B	code de l'icne
; mod	D2.L, D7.W

GETICONE:
	PUSH.W	D3

	LOAD.B	D2,(A5)+OOBICO	; D2 <-- code de l'icne

	TEST.W	(A5)+OOBVIE
	JUMP,NE 90$

	LOAD.W	D3,(A5)+OOBFIN
	ADD.B	D2,D3
	COMP.W	D3,#NBANIME
	JUMP,LS 90$

	CLR.B	D2
90$:
	POP.W	D3
	RET

;---------\\
; AGEICONE >
;=========/

; Fait vieillir une icne, jusqu' sa mort !

; in	A5.L	^description de l'objet
; out	-
; mod	D7.W

AGEICONE:
	PUSH.L	D3

	COMP.W	(A5)+OOBVIE,#-1	; icne immortelle ?
	JUMP,EQ 90$		; oui => 90$

	TEST.W	(A5)+OOBVIE	; icne morte ?
	JUMP,EQ 20$		; oui => 20$

	DEC.W	(A5)+OOBVIE	; oeuvre inxorable du temps ...
	JUMP	90$

20$:				; mort de l'icne =>
	TEST.W	(A5)+OOBFIN
	JUMP,NE 30$
	TEST.W	(A5)+OOBVIF
	JUMP,NE 30$

	CALL	MUS3OBJ		; bruit de la mort de l'objet
30$:
	LOAD.W	D3,(A5)+OOBFIN
	COMP.W	D3,#NBANIME
	JUMP,LO 40$
	SET.B	(A5)+OOBOLD
	JUMP	90$

40$:
	INC.W	(A5)+OOBVIF
	COMP.W	(A5)+OOBVIF,#VTANIME
	JUMP,LO 90$
	CLR.W	(A5)+OOBVIF

	INC.W	(A5)+OOBFIN
90$:
	POP.L	D3
	RET


;-----------\\
; MOVELICONE >
;===========/

; Dplace une icne sur l'cran en mode "load".

; in	D2.B	code de l'icne
;	D3.L	ancienne position (y;x)
;	D4.L	nouvelle position (y;x)
;	D5.L	dimensions (dy;dx)
; out	-
; mod	D7.W

MOVELICONE:
	PUSHM.L	D2,D3

	CALL	MOVECLR		; efface ce qui dpasse

	LOAD.B	D3,D2		; D3 <-- code de l'icne
	LOAD.W	D2,#SETDOT	; D2 <-- mode "load"
	CALL	DRICONE		; dessine la nouvelle icne

	POPM.L	D2,D3
	RET

;--------\\
; MOVECLR >
;--------/

; Efface la zone laisse vide aprs un dplacement.

; in	D3.L	ancienne position (y;x)
;	D4.L	nouvelle position (y;x)
;	D5.L	dimensions (dy;dx)
; out	-
; mod	D7.W

MOVECLR:
	PUSHM.L	D3..D5

	TEST.L	D3		; ancienne position existe ?
	JUMP,EQ 90$		; non => 90$

	PUSHM.L	D3..D5
	SUB.W	D4,D3
	JUMP,NC 10$
	NEG.W	D4
10$:
	COMP.W	D4,D5		; trop loin horizontalement ?
	JUMP,HS 60$		; oui => 60$

	SWAP.W	D3
	SWAP.W	D4
	SWAP.W	D5

	SUB.W	D4,D3
	JUMP,NC 15$
	NEG.W	D4
15$:
	COMP.W	D4,D5		; trop loin verticalement ?
	JUMP,HS 60$		; oui => 60$
	POPM.L	D3..D5

	PUSHM.L	D3,D4

	SWAP.W	D4
	SWAP.W	D5
	LOAD.W	D4,D5
	SWAP.W	D5
	SWAP.W	D4

	COMP.W	D3,D4
	JUMP,EQ 30$
	JUMP,HI 20$

	SUB.W	D4,D3
	CALL	DRCLEAR		; efface la zone  gauche
	JUMP	30$
20$:
	SUB.W	D4,D3
	NEG.W	D4
	ADD.W	D3,D5
	SUB.W	D3,D4
	CALL	DRCLEAR		; efface la zone  droite
30$:
	POPM.L	D3,D4

	LOAD.W	D4,D5
	SWAP.W	D3
	SWAP.W	D4
	SWAP.W	D5
	COMP.W	D3,D4
	JUMP,EQ 90$
	JUMP,HI 40$

	SUB.W	D4,D3
	SWAP.W	D3
	SWAP.W	D4
	CALL	DRCLEAR		; efface la zone en haut
	JUMP	90$
40$:
	SUB.W	D4,D3
	NEG.W	D4
	ADD.W	D3,D5
	SUB.W	D3,D4
	SWAP.W	D3
	SWAP.W	D4
	CALL	DRCLEAR		; efface la zone en bas
	JUMP	90$

60$:
	POPM.L	D3..D5
	LOAD.L	D4,D5
	CALL	DRCLEAR		; efface toute l'ancienne zone
90$:
	POPM.L	D3..D5
	RET





; Gestion du tableau de bord
; --------------------------



;-----------\\
; NEWSERVICE >
;===========/

; Cherche qui doit effectuer le service, et clignotte plus
; longtemps en cas de changement de service.

; in	-
; out	D4.W	bit zro indique  qui le service
; mod	D4.L, D7.W

NEWSERVICE:
	PUSHM.L	D3,A3

	CLR.L	D4
	LOAD.W	D4,(A6)+OCONJ
	ADD.W	D4,(A6)+OCONS	; D4 <-- total des points
	COMP.W	D4,#MAXPOINT*2	; prolongation ?
	JUMP,HS 10$		; oui => 10$ (change de service chaque fois)
	DIV.WU	D4,#5		; non => change toute les 5 balles
10$:
	LOAD.W	D3,#1		; D3 <-- juste une fois
	SWAP.W	D4
	TEST.W	D4
	JUMP,NE 15$
	LOAD.W	D3,#5		; D3 <-- beaucoup car changement de service
15$:
	SWAP.W	D4

20$:
	LOAD.L	A3,#R16"TMUSSERV1
	TEST.L	D4:#0
	JUMP,BC 22$
	LOAD.L	A3,#R16"TMUSSERV2
22$:
	CALL	PATATRA

	TEST.L	D4:#0
	JUMP,BS 30$

	CALL	JSERVICE	; allume service au joueur
	JUMP	35$
30$:
	CALL	SSERVICE	; allume service au SMAKY
35$:
	PUSH.W	D4
	LOAD.W	D4,#8
	NTREL	?DELMS
	POP.W	D4

	LOAD.L	A3,#R16"TMUSSERV1
	TEST.L	D4:#0
	JUMP,BS 42$
	LOAD.L	A3,#R16"TMUSSERV2
42$:
	CALL	PATATRA

	CALL	ESERVICE	; teint services

	PUSH.W	D4
	LOAD.W	D4,#8
	NTREL	?DELMS
	POP.W	D4

	DEC.W	D3
	JUMP,NE 20$
90$:
	POPM.L	D3,A3
	RET

;---------\\
; JSERVICE >
;=========/

; Allume la case de service du joueur.

; in	-
; out	-
; mod	D7.W

JSERVICE:
	TSET.B	(A6)+OSERV:#0
	JUMP,BS 20$
	CALL	IJSERVICE	; allume
20$:
	TCLR.B	(A6)+OSERV:#1
	JUMP,BC 30$
	CALL	ISSERVICE	; teint
30$:
	RET

;---------\\
; SSERVICE >
;=========/

; Allume la case de service du SMAKY.

; in	-
; out	-
; mod	D7.W

SSERVICE:
	TCLR.B	(A6)+OSERV:#0
	JUMP,BC 20$
	CALL	IJSERVICE	; teint
20$:
	TSET.B	(A6)+OSERV:#1
	JUMP,BS 30$
	CALL	ISSERVICE	; allume
30$:
	RET

;---------\\
; ESERVICE >
;=========/

; Efface les cases de service.

; in	-
; out	-
; mod	D7.W

ESERVICE:
	TCLR.B	(A6)+OSERV:#0
	JUMP,BC 20$
	CALL	IJSERVICE	; teint
20$:
	TCLR.B	(A6)+OSERV:#1
	JUMP,BC 30$
	CALL	ISSERVICE	; teint
30$:
	RET

;----------\\
; IJSERVICE >
;----------/

; Inverse la case de service du joueur.

; in	-
; out	-
; mod	D7.W

IJSERVICE:
	PUSHM.L	D3,D4

	LOAD.L	D3,#H'10000*POSYSJ+POSXSJ
	LOAD.L	D4,#H'10000*13+13
	CALL	DRINV

	POPM.L	D3,D4
	RET

;----------\\
; ISSERVICE >
;----------/

; Inverse la case de service du SMAKY.

; in	-
; out	-
; mod	D7.W

ISSERVICE:
	PUSHM.L	D3,D4

	LOAD.L	D3,#H'10000*POSYSS+POSXSS
	LOAD.L	D4,#H'10000*13+13
	CALL	DRINV

	POPM.L	D3,D4
	RET



;----------\\
; VIECOMPTE >
;==========/

; Fait clignotter le compteur du gagnant.

; in	-
; out	-
; mod	D7.W

VIECOMPTE:
	PUSH.L	D4

	INC.W	(A6)+OCOMPF
	COMP.W	(A6)+OCOMPF,#6
	JUMP,LO 90$
	CLR.W	(A6)+OCOMPF

	LOAD.W	D4,(A6)+OCONJ
	COMP.W	D4,(A6)+OCONS
	JUMP,EQ 60$
	JUMP,LO 40$
20$:				; joueur gagne =>
	CALL	IJCOMPTE
	CALL	CSCOMPTE
	JUMP	90$

40$:				; SMAKY gagne =>
	CALL	CJCOMPTE
	CALL	ISCOMPTE
	JUMP	90$

60$:				; galit =>
	TEST.W	D4		; zro  zro ?
	JUMP,EQ 90$		; oui => 90$
	CALL	IJCOMPTE
	CALL	ISCOMPTE
;	JUMP	90$

90$:
	POP.L	D4
	RET

;---------\\
; SJCOMPTE >
;=========/

; Allume le compteur du joueur.

; in	-
; out	-
; mod	D7.W

SJCOMPTE:
	TSET.B	(A6)+OCOMP:#0
	JUMP,BS 90$
	CALL	IIJCOMPTE
90$:
	RET

;---------\\
; CJCOMPTE >
;=========/

; Eteint le compteur du joueur.

; in	-
; out	-
; mod	D7.W

CJCOMPTE:
	TCLR.B	(A6)+OCOMP:#0
	JUMP,BC 90$
	CALL	IIJCOMPTE
90$:
	RET

;---------\\
; IJCOMPTE >
;=========/

; Inverse le compteur du joueur.

; in	-
; out	-
; mod	D7.W

IJCOMPTE:
	TNOT.B	(A6)+OCOMP:#0
	CALL	IIJCOMPTE
	RET

;---------\\
; SSCOMPTE >
;=========/

; Allume le compteur du SMAKY.

; in	-
; out	-
; mod	D7.W

SSCOMPTE:
	TSET.B	(A6)+OCOMP:#1
	JUMP,BS 90$
	CALL	IISCOMPTE
90$:
	RET

;---------\\
; CSCOMPTE >
;=========/

; Eteint le compteur du SMAKY.

; in	-
; out	-
; mod	D7.W

CSCOMPTE:
	TCLR.B	(A6)+OCOMP:#1
	JUMP,BC 90$
	CALL	IISCOMPTE
90$:
	RET

;---------\\
; ISCOMPTE >
;=========/

; Inverse le compteur du SMAKY.

; in	-
; out	-
; mod	D7.W

ISCOMPTE:
	TNOT.B	(A6)+OCOMP:#1
	CALL	IISCOMPTE
	RET

;----------\\
; IIJCOMPTE >
;----------/

; Inverse la case du compteur du joueur.

; in	-
; out	-
; mod	D7.W

IIJCOMPTE:
	PUSHM.L	D3,D4

	LOAD.L	D3,#H'10000*(POSYCJ-12)+(POSXCJ-2)
	LOAD.L	D4,#H'10000*15+23
	CALL	DRINV

	POPM.L	D3,D4
	RET

;----------\\
; IISCOMPTE >
;----------/

; Inverse la case du compteur du SMAKY.

; in	-
; out	-
; mod	D7.W

IISCOMPTE:
	PUSHM.L	D3,D4

	LOAD.L	D3,#H'10000*(POSYCS-12)+(POSXCS-2)
	LOAD.L	D4,#H'10000*15+23
	CALL	DRINV

	POPM.L	D3,D4
	RET


;---------\\
; SCOMPTE  >
;=========/

; Affiche le compteur du SMAKY.

; in	-
; out	-
; mod	D7.W

SCOMPTE:
	PUSHM.L	D4

	CALL	CSCOMPTE	; teint le compteur

	LOAD.W	D4,(A6)+OCONS
	LOAD.L	D3,#H'10000*POSYCS+POSXCS
	CALL	MAJCOMPTE

	POPM.L	D4
	RET

;---------\\
; JCOMPTE  >
;=========/

; Affiche le compteur du joueur.

; in	-
; out	-
; mod	D7.W

JCOMPTE:
	PUSHM.L	D4

	CALL	CJCOMPTE	; teint le compteur

	LOAD.W	D4,(A6)+OCONJ
	LOAD.L	D3,#H'10000*POSYCJ+POSXCJ
	CALL	MAJCOMPTE

	POPM.L	D4
	RET

;----------\\
; MAJCOMPTE >
;----------/

; Affiche un compteur sur l'cran.

; in	D4.W	compteur (..n)
;	D3.L	position dans l'cran
; out	-
; mod	D7.W

MAJCOMPTE:
	PUSHM.L	D2..D4

	LOAD.L	D2,D3

	TEST.B	(A6)+OINV	; fond de l'cran blanc ?
	JUMP,F	20$
	LOAD.B	D3,#AFINV
	LIB	?AFCAR		; passe en vide inverse
20$:
	LOAD.L	D3,D2
	LIB	?SETCURS

	AND.L	D4,#H'FFFF
	DIV.WU	D4,#100
	CLR.W	D4
	SWAP.W	D4		; D4 <-- 0..99

	DIV.WU	D4,#10
	LOAD.B	D3,D4
	ADD.B	D3,#'0
	LIB	?AFCAR		; affiche les dizaines

	LOAD.L	D3,D2
	ADD.W	D3,#13
	LIB	?SETCURS

	SWAP.W	D4
	LOAD.B	D3,D4
	ADD.B	D3,#'0
	LIB	?AFCAR		; affiche les units

	LOAD.B	D3,#AFDIR
	LIB	?AFCAR

	POPM.L	D2..D4
	RET





; Routines de GA (gomtrie analytique)
; -------------------------------------



;----------\\
; GAINTERHV >
;==========/

; Trouve le point d'intersection d'une droite quelconque P1(y,x)-P2(y,x)
; avec une droite horizontale ou verticale P3(y,x)-P4(y,x).

; in	D1.L	P1(y,x)
;	D2.L	P2(y,x)
;	D3.L	P3(y,x)
;	D4.L	P4(y,x)
; out	D0.L	I(y,x)
;	D7.W	erreur
; mod	D0.L, D7.W

GAINTERHV:
	PUSHM.L	D1..D4

	LOAD.W	D7,#1		; D7 <-- erreur

	COMP.W	D3,D4		; droite verticale ?
	JUMP,EQ 50$

	SWAP.W	D3
	SWAP.W	D4
	COMP.W	D3,D4		; droite horizontale ?
	JUMP,NE 90$
	SWAP.W	D4
	SWAP.W	D3
				; droite horizontale =>
	LOAD.L	D0,D3
	CALL	GAINTERH
	JUMP,NE 90$
	EX.L	D0,D3		; D0 <-- I(y,x)

	LOAD.W	D7,#1
	COMP.W	D0,D3
	JUMP,LO 90$
	COMP.W	D0,D4
	JUMP,HS 90$

	CLR.W	D7		; D7 <-- ok
	JUMP	90$

50$:				; droite verticale =>
	LOAD.L	D0,D3
	CALL	GAINTERV
	JUMP,NE 90$
	EX.L	D0,D3		; D0 <-- I(y,x)

	LOAD.W	D7,#1
	SWAP.W	D0
	SWAP.W	D3
	SWAP.W	D4
	COMP.W	D0,D3
	JUMP,LO 90$
	COMP.W	D0,D4
	JUMP,HS 90$
	SWAP.W	D0

	CLR.W	D7		; D7 <-- ok
90$:
	POPM.L	D1..D4
	TEST.W	D7		; retour EQ/NE
	RET

;---------\\
; GAINTERH >
;---------/

; Trouve le point d'intersection d'une droite P1(y,x)-P2(y,x)
; quelconque avec une droite horizontale.

;	      (P2x-P1x) * (Iy-P1y)
;	Ix = ---------------------- + P1x
;	            (P2y-P1y)

; in	D1.L	P1(y,x)
;	D2.L	P2(y,x)
;	D3.L	I(y,?)
; out	D3.L	I(y,x)
;	D7.W	erreur
; mod	D3.L, D7.W

GAINTERH:
	SWAP.W	D1
	SWAP.W	D2		; swap x <--> y
	SWAP.W	D3
	CALL	GAINTERV	; comme si vertical !
	SWAP.W	D3
	SWAP.W	D2		; swap y <--> x
	SWAP.W	D1
	TEST.W	D7		; retour EQ/NE
	RET

;---------\\
; GAINTERV >
;---------/

; Trouve le point d'intersection d'une droite P1(y,x)-P2(y,x)
; quelconque avec une droite verticale.

;	      (P2y-P1y) * (Ix-P1x)
;	Iy = ---------------------- + P1y
;	            (P2x-P1x)

; in	D1.L	P1(y,x)
;	D2.L	P2(y,x)
;	D3.L	I(?,x)
; out	D3.L	I(y,x)
;	D7.W	erreur
; mod	D3.L, D7.W

GAINTERV:
	PUSHM.L	D0..D2

	LOAD.W	D7,#1		; D7 <-- erreur

	SUB.W	D2,D1		; D2 <-- P2x-P1x
	JUMP,EQ 90$
	SWAP.W	D1
	SWAP.W	D2
	SUB.W	D2,D1		; D2 <-- P2y-P1y
	SWAP.W	D1

	LOAD.W	D0,D3
	SUB.W	D0,D1		; D0 <-- Ix-P1x
	MUL.WA	D0,D2		; D2 <-- (P2y-P1) * (Ix-P1x)
	SWAP.W	D2
	DIV.WA	D0,D2
	SWAP.W	D1
	ADD.W	D0,D1

	SWAP.W	D3
	LOAD.W	D3,D0		; D3 <-- Iy
	SWAP.W	D3

	CLR.W	D7		; D7 <-- ok
90$:
	POPM.L	D0..D2
	TEST.W	D7		; retour EQ/NE
	RET






; Gestion des bruits
; ------------------



;--------\\
; MUS1OBJ >
;========/

; Fait entendre un bruit numro 1 li  un objet spcifique.

; in	A5.L	^description de l'objet
; out	-
; mod	D7.W

MUS1OBJ:
	PUSH.L	A3

	LOAD.L	A3,#R16"TMUS
	ADD.W	A3,(A5)+OOBMU1
	CALL	PATATRA

	POP.L	A3
	RET

;--------\\
; MUS2OBJ >
;========/

; Fait entendre un bruit numro 2 li  un objet spcifique.

; in	A5.L	^description de l'objet
; out	-
; mod	D7.W

MUS2OBJ:
	PUSH.L	A3

	LOAD.L	A3,#R16"TMUS
	ADD.W	A3,(A5)+OOBMU2
	CALL	PATATRA

	POP.L	A3
	RET

;--------\\
; MUS3OBJ >
;========/

; Fait entendre un bruit numro 3 li  un objet spcifique.

; in	A5.L	^description de l'objet
; out	-
; mod	D7.W

MUS3OBJ:
	PUSH.L	A3

	LOAD.L	A3,#R16"TMUS
	ADD.W	A3,(A5)+OOBMU3
	CALL	PATATRA

	POP.L	A3
	RET

;--------\\
; PATATRA >
;========/

; Fait un bruit rigolo !

; in	A3.L	^table de bruit
; out	-
; mod	D7.W

PATATRA:
	PUSH.L	A4

	LOAD.L	A4,A3
	TEST.W	(A4)
	JUMP,EQ 90$
	LIB	?PLAY
90$:
	POP.L	A4
	RET



TMUS:

TMUSCOLB1:
	.W	PERIODE+3000,PERIODE+3001,PERIODE+3002,H'100*20+0
	.W	0

TMUSCOLR1:
	.W	PERIODE+2000,PERIODE+2001,PERIODE+2002,H'100*20+0
	.W	0

TMUSENDB1:
	.W	PERIODE+3567,PERIODE+3254,BRUIT+31,H'100*50+0
	.W	0


TMUSCOLBRI1:
	.W	PERIODE+3000,PERIODE+3001,PERIODE+3002,H'100*10+0
	.W	0

TMUSCOLBRI2:
	.W	BRUIT+4,SILENCE,SILENCE,H'100*50+0
	.W	0


TMUSSERV1:
	.W	NOTE+OCTAVE*6,NOTE+OCTAVE*5,NOTE+OCTAVE*4,H'100*10+0
	.W	0
TMUSSERV2:
	.W	NOTE+OCTAVE*5,NOTE+OCTAVE*4,NOTE+OCTAVE*3,H'100*10+0
	.W	0

TMUSSERVICE:
	.W	PERIODE+1000,SILENCE,SILENCE,H'100*255+2
	.W	PERIODE+900,SILENCE,SILENCE,H'100*255+2
	.W	PERIODE+800,SILENCE,SILENCE,H'100*255+2
	.W	PERIODE+700,SILENCE,SILENCE,H'100*255+2
	.W	PERIODE+600,SILENCE,SILENCE,H'100*255+2
	.W	PERIODE+500,SILENCE,SILENCE,H'100*255+2
	.W	PERIODE+400,SILENCE,SILENCE,H'100*255+2
	.W	PERIODE+300,SILENCE,SILENCE,H'100*255+2
	.W	PERIODE+200,SILENCE,SILENCE,H'100*255+2
	.W	PERIODE+100,SILENCE,SILENCE,H'100*2+2
	.W	0


TMUSYOUPIE:
	.W	PERIODE+800,PERIODE+400,PERIODE+600,H'100*10+4
	.W	PERIODE+300,PERIODE+600,PERIODE+400,H'100*10+4
	.W	PERIODE+250,PERIODE+500,PERIODE+1000,H'100*10+4
	.W	PERIODE+600,PERIODE+300,PERIODE+400,H'100*10+4
	.W	PERIODE+1000,PERIODE+500,PERIODE+1500,H'100*10+4
	.W	PERIODE+500,PERIODE+1000,PERIODE+750,H'100*10+4
	.W	PERIODE+200,PERIODE+300,PERIODE+400,H'100*10+4
	.W	PERIODE+400,PERIODE+500,PERIODE+600,H'100*10+1
	.W	0

TMUSPERDU:
	.W	NOTE+14,NOTE+12+14,NOTE+14+34,H'100*50+30
	.W	NOTE+13,NOTE+12+13,NOTE+14+33,H'100*50+30
	.W	NOTE+12,NOTE+12+12,NOTE+14+32,H'100*50+30
	.W	NOTE+11,NOTE+12+11,NOTE+14+31,H'100*60+0
	.W	0





; Gestion de la souris
; --------------------



;--------\\
; IFMOUSE >
;========/

; Donne la position de la souris dans la swdo.

; in	-
; out	D4.L	position de la souris (y;x)
;	D7.W	erreur
; mod	D4.L, D7.W

IFMOUSE:
	PUSH.L	D3

	LIB	?IFMOUSE
	JUMP',NE 90$

	SUB.W	D4,(A0)+ODFFX
	JUMP',HS 20$
	CLR.W	D4
	LOAD.W	D7,#ERDIOUT
20$:
	SWAP.W	D4
	SUB.W	D4,(A0)+ODFFY
	JUMP',HS 30$
	CLR.W	D4
	LOAD.W	D7,#ERDIOUT
30$:
	SWAP.W	D4
90$:
	POP.L	D3
	TEST.W	D7		; retour EQ/NE
	RET

;--------\\
; PMOUSE  >
;========/

; Positionne la souris en (y;x).

; in	D4.L	nouvelle position y;x
; out	-
; mod	D7.W

PMOUSE:
	PUSHM.L	D3,D4,D6,A4

	LOAD.L	(A6)+OMOUPO,D4	; mm. la position de la souris

	ADD.W	D4,(A0)+ODFFX
	SWAP.W	D4
	ADD.W	D4,(A0)+ODFFY
	SWAP.W	D4

; Ramne la position dans la fentre si elle en sort.

	TEST.W	D4		; trop  gauche ?
	JUMP',NC 10$
	CLR.W	D4
10$:
	COMP.W	D4,(A0)+ODFDX	; trop  droite ?
	JUMP',LT 15$
	LOAD.W	D4,(A0)+ODFDX
	DEC.W	D4
15$:
	SWAP.W	D4
	TEST.W	D4		; trop en haut ?
	JUMP',NC 20$
	CLR.W	D4
20$:
	COMP.W	D4,(A0)+ODFDY	; trop en bas ?
	JUMP',LT 25$
	LOAD.W	D4,(A0)+ODFDY
	DEC.W	D4
25$:
	SWAP.W	D4

; Calcul la position absolue dans le grand bitmap $DIS_0.

	ADD.W	D4,(A0)+ODFX
	SWAP.W	D4
	ADD.W	D4,(A0)+ODFY
	SWAP.W	D4		; D4 <-- position dans $DIS_0 !

; Envoie la commande secrte et mystrieuse de positionnement.

 	LOAD.L	A4,#(A6)+OBUDIS+1
	LOAD.B	(A4)+0,#'P	; <P>
	LOAD.L	(A4)+1,D4	; <yy> <xx>
	CLR.B	(A4)+5
	LOAD.W	D3,#TYPIO	; D3 <-- type du driver souris
	LIB	?GCHMOU		; D6 <-- canal souris
	FOS	?COMMAND

	POPM.L	D3,D4,D6,A4
	RET





; Routines graphiques rapides
; ---------------------------



;--------\\
; PREPBRI >
;========/

; Prpare un caractre pour pouvoir l'animer rapidement
; en mode inverse (petite recette de cuisine secrte) !
; ATTENTION: On gnre directement la matrice dans le
; gencar, d'o incompatibilit si plusieurs programmes
; utilisent ce mme gencar.

; in	D3.B	code de l'icne
; out	-
; mod	D7.W

PREPBRI:
	PUSHM.L	D1..D6,A2..A4

	LOAD.L	A2,(A6)+OPGICO	; A2 <-- ^gencar IMP64

	AND.W	D3,#H'FF
	MUL.WU	D3,(A2)+OGCMSB
	LOAD.L	A3,#(A2)+OGCMAT
	ADD.L	A3,D3		; A3 <-- ^matrice source

	LOAD.L	A4,A3
	ADD.W	A4,(A2)+OGCMSB	; A4 <-- ^matrice destination

	CLR.W	D5
	LOAD.B	D5,(A2)+OGCMWB	; D5 <-- largeur en bytes
	LOAD.W	D6,D5

	LOAD.L	D3,#H'10000*IDYBRI
	CLR.L	D4

	LOAD.L	D1,#H'10000*IDYBRI+IDXBRI
	LOAD.W	D2,#SETDOT
	CALL	DRRASTER

	LOAD.L	A3,A4
	LOAD.W	D2,#INVDOT
	CALL	DRRASTER

	POPM.L	D1..D6,A2..A4
	RET


;--------\\
; DRICONE >
;========/

; Dessine une icne de IPP64.

; in	D3.B	code de l'icne (0..127)
;	D4.L	position coin inf/gauche (y;x)
;	D5.L	dimensions (dy;dx)
;	D2.W	mode
; out	-
; mod	D7.W

DRICONE:
	PUSHM.L	D0..D5,A1,A2,A4

	CLR.W	D1
	LOAD.B	D1,D3		; D1 <-- code de l'icne

	LOAD.L	A4,(A6)+OPGICO	; A4 <-- ^gencar IPP64

	LOAD.L	D3,D5		; D3 <-- dimensions

	CLR.W	D5
	LOAD.B	D5,(A4)+OGCMWB	; D5 <-- largeur en bytes

	MUL.WU	D1,(A4)+OGCMSB
	ADD.L	A4,#OGCMAT
	ADD.L	A4,D1		; A4 <-- ^la bonne matrice

	LOAD.W	D1,D2		; D1 <-- mode
	CLR.B	D2		; D2 <-- pas d'inversion vido
	COMP.B	D1,#INVDOT
	JUMP,EQ 50$
	TEST.B	(A6)+OINV	; fond de l'cran blanc ?
	JUMP,F	50$		; non => 50$
	NOT.B	D2		; D2 <-- inversion vido
50$:
	LOAD.L	A2,A0		; A2 <-- ^descripteur de la fentre
	LOAD.L	A1,(A6)+OADMATRIX
	CALL	(A1)		; appel de GRA_MATRIX

	POPM.L	D0..D5,A1,A2,A4
	RET


;--------\\
; DRRECT  >
;========/

; Dessine un rectangle.

; in	D3.L	coordonne origine (y;x)
;	D4.L	dimensions (dy;dx)
;	D2.W	mode
; out	-
; mod	D7.W

DRRECT:
	PUSHM.L	D3..D5

	LOAD.L	D5,D4		; D5 <-- dimensions (dy;dx)

	AND.L	D4,#H'FFFF
	CALL	DRLINE		; trace ligne suprieure

	LOAD.L	D4,D5
	CLR.W	D4
	CALL	DRLINE		; trace ligne de droite

	LOAD.L	D4,D5
	AND.L	D4,#H'FFFF
	NEG.W	D4
	CALL	DRLINE		; trace ligne infrieure

	LOAD.L	D4,D5
	SWAP.W	D4
	NEG.W	D4
	SWAP.W	D4
	CLR.W	D4
	CALL	DRLINE		; trace ligne de gauche

	POPM.L	D3..D5
	RET


;---------\\
; DRRASTER >
;=========/

; Dplace une surface rectangulaire mmoire/cran --> mmoire/cran.

; in	D3.L	coordonne source (y;x)
;	A3.L	^mmoire source/^nil si cran
;	D5.W	Iy source (si mmoire)
;	----
;	D4.L	coordonne destination (y;x)
;	A4.L	^mmoire destination/^nil si cran
;	D6.W	Iy destination (si mmoire)
;	----
;	D1.L	hauteur/largeur (y;x)
;	D2.B	opration (INVDOT, SETDOT, CLRDOT ou LOADDOT)
; out	-
; mod	D7.W

DRRASTER:
	PUSHM.L	D1,D2,A1,A2

	TEST.W	D1		; dx <= 0 ?
	JUMP',LE 90$
	SWAP.W	D1
	TEST.W	D1		; dy <= 0 ?
	JUMP',LE 90$
	SWAP.W	D1

	EX.L	D1,D2		; D2/D1 <-- mode/dimensions
	LOAD.L	A2,A0		; A2 <-- ^descripteur de la fentre
	LOAD.L	A1,(A6)+OADRASTER
	CALL	(A1)		; appel de GRA_RASTER
90$:
	POPM.L	D1,D2,A1,A2
	RET


;-------\\
; DRDOT  >
;=======/

; Dessine un point.

; in	D3.L	coordonne (y;x)
;	D2.W	mode
; out	-
; mod	D7.W

DRDOT:
	PUSHM.L	D1..D4,A1,A2

	LOAD.W	D1,D2		; D1 <-- mode
	LOAD.L	D4,D3		; D4 <-- y;x
	LOAD.L	A2,A0		; A2 <-- ^descripteur de la fentre
	LOAD.L	A1,(A6)+OADDOT
	CALL	(A1)		; appel de GRA_DOT

	POPM.L	D1..D4,A1,A2
	RET


;--------\\
; DRLINE  >
;========/

; Dessine un segment de droite.

; in	D3.L	coordonne origine (y;x)
;	D4.L	dimensions (dy;dx)
;	D2.W	mode
; out	D3.L	coordonne d'arrive (y;x)
; mod	D3.L, D7.W

DRLINE:
	PUSHM.L	D1,D2,D4,A1,A2

	LOAD.W	D1,D2		; D1 <-- mode
	EX.L	D3,D4		; D4/D3 <-- y;x/dy;dx
	LOAD.L	A2,A0		; A2 <-- ^descripteur de la fentre
	LOAD.L	A1,(A6)+OADLINE
	CALL	(A1)		; appel de GRA_LINE

	EX.L	D3,D4
	ADD.W	D3,D4		; D3 <-- arrive en X
	SWAP.W	D3
	SWAP.W	D4
	ADD.W	D3,D4		; D3 <-- arrive en Y
	SWAP.W	D3
;	SWAP.W	D4

	POPM.L	D1,D2,D4,A1,A2
	RET


;----------\\
; DRELLIPSE >
;==========/

; Dessine une ellipse, ou un arc d'ellipse.

; in	D3.L	coordonne centre (y;x)
;	D4.L	rayons (dy;dx)
;	D2.W	mode
;	D1.B	bitmap des octants  dessiner
; out	-
; mod	D7.W

DRELLIPSE:
	PUSHM.L	D1..D4,A1,A2

	EX.L	D1,D2		; D2/D1 <-- mode/octants
	EX.L	D3,D4		; D4/D3 <-- y;x/dy;dx
	LOAD.L	A2,A0		; A2 <-- ^descripteur de la fentre
	LOAD.L	A1,(A6)+OADELLIPSE
	CALL	(A1)		; appel de GRA_ELLIPSE

	POPM.L	D1..D4,A1,A2
	RET


;---------\\
; DRTRADEF >
;=========/

; Dfinit une trame.

; in	D3.L	trame
;	D4.L	trame
; out	-
; mod	D7.W

DRTRADEF:
	PUSHM.L	D1..D4

	COMP.B	(A6)+OMACHINE,#SMAKY100
	JUMP',NE 80$
				; si SMAKY100 =>
	LOAD.W	D1,#4-1
20$:
	CALL	FLIP
	RR.L	D3,#8
	DECJ.W,NMO D1,20$

	EX.L	D3,D4
	LOAD.W	D1,#4-1
30$:
	CALL	FLIP
	RR.L	D3,#8
	DECJ.W,NMO D1,30$
	EX.L	D4,D3
80$:
	LOAD.L	(A0)+ODFTRA+0,D3
	LOAD.L	(A0)+ODFTRA+4,D4

	POPM.L	D1..D4
	RET

;--------\\
; FLIP    >
;--------/

; Permute tous les bits de D3.B. Pas de boucle pour tre
; rapide, et pas de table de 256 bytes pour conomiser la RAM !

; in	D3.B	byte
; out	D3.B	byte "flipp"
; mod	D2.B, D3.B

FLIP:
	RLX.B	D3
	RRX.B	D2		; D2 <-- bit 0
	RLX.B	D3
	RRX.B	D2		; D2 <-- bit 1
	RLX.B	D3
	RRX.B	D2		; D2 <-- bit 2
	RLX.B	D3
	RRX.B	D2		; D2 <-- bit 3
	RLX.B	D3
	RRX.B	D2		; D2 <-- bit 4
	RLX.B	D3
	RRX.B	D2		; D2 <-- bit 5
	RLX.B	D3
	RRX.B	D2		; D2 <-- bit 6
	RLX.B	D3
	RRX.B	D2		; D2 <-- bit 7

	LOAD.B	D3,D2		; D3 <-- byte "flipp"
	RET


;---------\\
; DRTRAME  >
;=========/

; Dessine une surface rectangulaire.

; in	D3.L	coordonne origine (y;x)
;	D4.L	dimensions (dy;dx)
;	D2.W	mode
; out	-
; mod	D7.W

DRTRAME:
	PUSHM.L	D1..D4,A1,A2,A4

	TEST.W	D4		; dx <= 0 ?
	JUMP',LE 90$
	SWAP.W	D4
	TEST.W	D4		; dy <= 0 ?
	JUMP',LE 90$
	SWAP.W	D4

	LOAD.W	D1,D2		; D1 <-- mode
	EX.L	D3,D4		; D4/D3 <-- y;x/dy;dx
	LOAD.L	A4,#(A0)+ODFTRA	; A4 <-- ^trame utilisateur
	LOAD.L	A2,A0		; A2 <-- ^descripteur de la fentre
	LOAD.L	A1,(A6)+OADTRAME
	CALL	(A1)		; appel de GRA_TRAME
90$:
	POPM.L	D1..D4,A1,A2,A4
	RET


;--------\\
; DRZONE  >
;========/

; Efface, allume ou inverse une surface rectangulaire.

; in	D3.L	coordonne origine (y;x)
;	D4.L	dimensions (dy;dx)
;	D2.W	mode
; out	-
; mod	D7.W

DRZONE:
	COMP.B	D2,#INVDOT
	JUMP,EQ DRINV
	COMP.B	D2,#SETDOT
	JUMP,EQ DRSET

;---------\\
; DRCLEAR  >
;=========/

; Efface une surface rectangulaire.

; in	D3.L	coordonne origine (y;x)
;	D4.L	dimensions (dy;dx)
; out	-
; mod	D7.W

DRCLEAR:
	TEST.B	(A6)+OINV	; fond de l'cran blanc ?
	JUMP,T	DRSET0		; oui => DRSET0
DRCLEAR0:
	PUSHM.L	D1..D4,A1,A2

	TEST.W	D4		; dx <= 0 ?
	JUMP',LE 90$
	SWAP.W	D4
	TEST.W	D4		; dy <= 0 ?
	JUMP',LE 90$
	SWAP.W	D4

	LOAD.W	D1,D2		; D1 <-- mode
	EX.L	D3,D4		; D4/D3 <-- y;x/dy;dx
	LOAD.L	A2,A0		; A2 <-- ^descripteur de la fentre
	LOAD.L	A1,(A6)+OADCLEAR
	CALL	(A1)		; appel de GRA_SET
90$:
	POPM.L	D1..D4,A1,A2
	RET

;---------\\
; DRSET    >
;=========/

; Allume une surface rectangulaire.

; in	D3.L	coordonne origine (y;x)
;	D4.L	dimensions (dy;dx)
; out	-
; mod	D7.W

DRSET:
	TEST.B	(A6)+OINV	; fond de l'cran blanc ?
	JUMP,T	DRCLEAR0	; oui => DRCLEAR0
DRSET0:
	PUSHM.L	D1..D4,A1,A2

	TEST.W	D4		; dx <= 0 ?
	JUMP',LE 90$
	SWAP.W	D4
	TEST.W	D4		; dy <= 0 ?
	JUMP',LE 90$
	SWAP.W	D4

	LOAD.W	D1,D2		; D1 <-- mode
	EX.L	D3,D4		; D4/D3 <-- y;x/dy;dx
	LOAD.L	A2,A0		; A2 <-- ^descripteur de la fentre
	LOAD.L	A1,(A6)+OADSET
	CALL	(A1)		; appel de GRA_SET
90$:
	POPM.L	D1..D4,A1,A2
	RET

;---------\\
; DRINV    >
;=========/

; Inverse une surface rectangulaire.

; in	D3.L	coordonne origine (y;x)
;	D4.L	dimensions (dy;dx)
; out	-
; mod	D7.W

DRINV:
	PUSHM.L	D1..D4,A1,A2

	TEST.W	D4		; dx <= 0 ?
	JUMP',LE 90$
	SWAP.W	D4
	TEST.W	D4		; dy <= 0 ?
	JUMP',LE 90$
	SWAP.W	D4

	LOAD.W	D1,D2		; D1 <-- mode
	EX.L	D3,D4		; D4/D3 <-- y;x/dy;dx
	LOAD.L	A2,A0		; A2 <-- ^descripteur de la fentre
	LOAD.L	A1,(A6)+OADINV
	CALL	(A1)		; appel de GRA_INV
90$:
	POPM.L	D1..D4,A1,A2
	RET


;--------\\
; DRFILL  >
;========/

; Rempli une surface quelconque.

; in	D3.L	point de remplissage (y;x)
; out	D7.W	erreur
; mod	D7.W

DRFILL:
	PUSHM.L	D1..D4,A1,A2

	LOAD.L	D4,D3		; D4 <-- y;x
	LOAD.L	A2,A0		; A2 <-- ^descripteur de la fentre
	LOAD.L	A1,(A6)+OADFILLO
	CALL	(A1)		; appel de GRA_FILLO
	PUSH.W	D7
	LOAD.L	A1,(A6)+OADFILLC
	CALL	(A1)		; appel de GRA_FILLC
	POP.W	D7

	POPM.L	D1..D4,A1,A2
	TEST.W	D7		; retour EQ/NE
	RET



;--------\\
; AFIMAGE >
;========/

; Affiche une image, sans la conserver en mmoire.

; in	A3.L	^nom de l'image
; out	D7.W	erreur
; mod	D7.W

AFIMAGE:
	PUSH.L	A4

	CALL	LOADIMAGE	; charge l'image en mmoire
	JUMP,NE 90$
	CALL	SHOWIMAGE	; affiche l'image
	CALL	KILLIMAGE	; libre la mmoire
90$:
	POP.L	A4
	TEST.W	D7		; retour EQ/NE
	RET

;----------\\
; LOADIMAGE >
;==========/

; Charge une image en mmoire.

; in	A3.L	^nom de l'image
; out	A4.L	^image
;	D4.L	dimensions (dy;dx)
;	D7.W	erreur
; mod	A4.L, D7.W, A4.L

LOADIMAGE:
	PUSHM.L	D0,D1,D3,D6,A1..A3,A5

	LOAD.L	A5,A3		; A5 <-- ^nom de l'image

	LOAD.L	D4,#LGHIMA
	LOAD.W	D1,#MTYPCP
	GESMEM	?GETMEM		; demande un buffer pour l'en-tte
	JUMP,NE 90$
	LOAD.L	A2,A4		; A2 <-- ^en-tte

	LOAD.W	D3,#2^BOPRD!2^BOPSYS ; D3 <-- mode d'ouverture
	FOS	?OPEN		; ouvre l'image
	JUMP,NE 84$

	LOAD.L	A4,A2
	FOS	?RDBYTE		; lit l'en-tte
	JUMP,NE 82$

	COMP.B	(A2)+OIMTYP,#H'82 ; image du LAMI ?
	JUMP',NE 20$		; non => 20$
				; oui =>
	CLR.B	D3
	LOAD.L	D4,#256
	FOS	?SPOS		; saute la stupide en-tte de 256 bytes !
	JUMP,NE 82$

	LOAD.L	D4,#LGHIMA
	FOS	?RDBYTE		; lit l'en-tte
	JUMP,NE 82$
20$:
	LOAD.W	D0,(A2)+OIMDLX	; D0 <-- largeur de l'image
	LOAD.W	D1,(A2)+OIMDLY	; D1 <-- hauteur de l'image

	LOAD.W	D4,D0
	SR.W	D4,#3
	MUL.WU	D4,D1		; D4 <-- largeur*hauteur/8
	ADD.L	D4,#IMLBUF	; D4 <-- rserve pour codage
	PUSH.W	D1
	LOAD.W	D1,#MTYPCP
	GESMEM	?GETMEM		; demande un buffer pour toute l'image
	POPM.W	D1
	JUMP,NE 82$
	LOAD.L	A1,#(A4)+IMLBUF	; A1 <-- ^image

	LOAD.L	D4,(A2)+OIMNBB	; D4 <-- longueur  lire
	TEST.B	(A2)+OIMCOD	; image code ?
	JUMP',NE 30$		; oui => 30$
				; non =>
	LOAD.L	A4,A1
	FOS	?RDBYTE		; lit toute l'image dcode
	JUMP,NE 80$
	JUMP'	35$
30$:
	FOS	?RDBYTE		; lit toute l'image code
	JUMP,NE 80$
	LOAD.L	A3,A1
	GRA_	DECOIMA		; dcode l'image ...
	JUMP,NE 80$
35$:
	TEST.B	(A6)+OINV	; fond de l'cran blanc ?
	JUMP,T	40$		; oui => 40$
	CALL	INVIMAGE	; inverse compltement l'image
40$:
	LOAD.L	A4,A1		; A4 <-- ^image

	LOAD.W	D4,D1
	SWAP.W	D4
	LOAD.W	D4,D0		; D4 <-- dimensions de l'image

	CLR.W	D7		; D7 <-- ok
	JUMP	82$

80$:
	PUSH.W	D7
	LOAD.L	A4,#(A1)-IMLBUF
	LOAD.W	D1,#MTYPCP
	GESMEM	?GIVMEM		; rend la mmoire de l'image
	POP.W	D7
82$:
	PUSH.W	D7
	FOS	?CLOSE		; ferme l'image
	POP.W	D7
84$:
	PUSHM.L	D7,A4
	LOAD.L	A4,A2
	LOAD.W	D1,#MTYPCP
	GESMEM	?GIVMEM		; rend le buffer pour l'en-tete
	POPM.L	D7,A4
90$:
	POPM.L	D0,D1,D3,D6,A1..A3,A5
	TEST.W	D7		; retour EQ/NE
	RET

;----------\\
; SHOWIMAGE >
;==========/

; Affiche une image dans la (sous-)fentre.
; Si elle est trop petite, elle est centre au milieu de l'cran.
; Si elle est trop grande, on affiche sa partie centrale.

; in	A4.L	^image
;	D4.L	dimensions (dy;dx)
; out	-
; mod	D7.W

SHOWIMAGE:
	PUSHM.L	D0,D1,D3,D4,A3

	LIB	?AFTIM
	.B	NOCURS		; plus de curseur
	.B	EOP		; efface toute la fentre
	.B	0
	.EVEN

	LOAD.W	D0,D4		; D0 <-- largeur de l'image
	SWAP.W	D4
	LOAD.W	D1,D4		; D1 <-- hauteur de l'image

	LOAD.L	A3,#(A6)+OBUDIS	; A3 <-- ^buffer pour DRAWRASTER

	LOAD.W	D3,D0
	SR.W	D3,#3
	LOAD.W	(A3)+10,D3	; source: <ii>
	CLR.W	(A3)+20		; destination: <ii>

	LOAD.L	D4,(A0)+ODFFDY	; D4 <-- dimensions de la fentre
	COMP.W	D0,D4		; image trop large ?
	JUMP',HI 50$		; oui => 50$
	CLR.W	(A3)+2		; source: <xx>
	LOAD.W	(A3)+22,D0	; image: <dxx>
	SUB.W	D4,D0
	SR.W	D4,#1
	LOAD.W	(A3)+12,D4	; destination: <xx>
	JUMP'	55$
50$:
	SUB.W	D0,D4
	SR.W	D0,#1
	LOAD.W	(A3)+2,D0	; source: <xx>
	CLR.W	(A3)+12		; destination: <xx>
	LOAD.W	(A3)+22,D4	; image: <dxx>
55$:
	SWAP.W	D4
	COMP.W	D1,D4		; image trop haute ?
	JUMP',HI 60$		; oui => 60$
	CLR.W	(A3)+4		; source: <yy>
	LOAD.W	(A3)+24,D1	; image: <dyy>
	SUB.W	D4,D1
	SR.W	D4,#1
	LOAD.W	(A3)+14,D4	; destination: <yy>
	JUMP'	65$
60$:
	SUB.W	D1,D4
	SR.W	D1,#1
	LOAD.W	(A3)+4,D1	; source: <yy>
;	ADD.W	(A3)+14,#0	; destination: <yy>
	LOAD.W	(A3)+24,D4	; image: <dyy>
65$:
	LOAD.W	(A3)+0,#DRAWRASTER
	LOAD.L	(A3)+6,A4	; source: <pppp>
	CLR.L	(A3)+16		; destination: <pppp>
	LOAD.B	(A3)+26,#SETDOT	; image: <mode>
	LOAD.W	D3,#1+26	; D3 <-- longueur
	LIB	?STRING		; affiche l'image

	POPM.L	D0,D1,D3,D4,A3
	RET

;----------\\
; KILLIMAGE >
;==========/

; Libre la mmoire d'une image.

; in	A4.L	^image
; out	-
; mod	-

KILLIMAGE:
	PUSHM.L	D1,D7,A4

	LOAD.L	A4,#(A4)-IMLBUF
	LOAD.W	D1,#MTYPCP
	GESMEM	?GIVMEM		; rend la mmoire de l'image

	POPM.L	D1,D7,A4
	RET

;---------\
; INVIMAGE >
;---------/

; Inverse compltement une image.

; in	A1.L	^image
;	D0.W	largeur
;	D1.W	hauteur
; out	-
; mod	D7.W

INVIMAGE:
	PUSHM.L	D0,A1

	SR.W	D0,#3		; D0 <-- largeur en bytes
	MUL.WU	D0,D1		; D0 <-- nb total de bytes
	SR.W	D0,#2		; D0 <-- nb total de .L
	DEC.W	D0		; D0 <-- -1  cause NMO
20$:
	NOT.L	(A1+)
	DECJ.W,NMO D0,20$

	POPM.L	D0,A1
	RET






; Tirage de nombres alatoires
; ----------------------------



;--------\\
; COUPSAC >
;========/

; Coup de sac pour le gnrateur alatoire.

; in	-
; out	-
; mod	D7.W

COUPSAC:
	PUSHM.L	D3,D4

	LIB	?RDCLOCK	; D3/D4 <-- date et heure
	RR.L	D3,#3
	RL.L	D4,#7		; savante cuisine
	NOT.L	D3
	XOR.L	D4,D3
	LOAD.L	(A6)+OHAZA+0,D3
	LOAD.L	(A6)+OHAZA+4,D4

	LOAD.W	D3,#10-1
20$:
	CALL	HAZARD		; tire qq nombres
	DECJ.W,NMO D3,20$

	POPM.L	D3,D4
	RET

;---------\\
; MMHAZARD >
;=========/

; Tire un nombre alatoire (16 bits) compris entre deux bornes.

; in	D3.W	+/- borne infrieure (min)
;	D4.W	+/- borne suprieure (max+1)
; out	D4.W	+/- nombre alatoire: D3 <= n < D4
; mod	D4.L, D7.W

MMHAZARD:
	PUSH.W	D2

	LOAD.W	D2,D4
	SUB.W	D2,D3		; D2 <-- sup - inf
	CALL	HAZARD

	AND.L	D4,#H'FFFF
	DIV.WU	D4,D2
	SWAP.W	D4		; D4 <-- reste de la division
	ADD.W	D4,D3

	POP.W	D2
	RET

;--------\\
; HAZARD  >
;========/

; Tire un nombre alatoire de 32 bits.
; On utilise un registre  dcalage de 63 bits, avec un XNOR entre
; les bits 0 et 60 pour calculer le nouveau bit inject.

; in	-
; out	D4.L	nombre
; mod	D4.L, D7.W

HAZARD:
	PUSHM.L	D2,D3

	LOAD.W	D2,#32-1

	LOAD.L	D3,(A6)+OHAZA+0
	LOAD.L	D4,(A6)+OHAZA+4
10$:
	TEST.L	D4:#1
	JUMP,BC 20$
	TEST.L	D3:#30
	JUMP,BC 35$
	JUMP	30$
20$:
	TEST.L	D3:#30
	JUMP,BS 35$
30$:
	CLRX
	RRX.L	D3,#1
	RRX.L	D4,#1
	JUMP	40$
35$:
	SETX
	RRX.L	D3,#1
	RRX.L	D4,#1
40$:
	LOAD.L	(A6)+OHAZA+0,D3
	LOAD.L	(A6)+OHAZA+4,D4

	DECJ.W,NMO D2,10$

	POPM.L	D2,D3
	RET







; Debug
; -----


DRD0:
	PUSHM.L	D2..D4

	LOAD.W	D2,#INVDOT

	LOAD.L	D3,D0
	SUB.W	D3,#10
	CLR.L	D4
	LOAD.W	D4,#20
	LIB	?DRSEG

	LOAD.L	D3,D0
	SWAP.W	D3
	SUB.W	D3,#10
	SWAP.W	D3
	LOAD.W	D4,#20
	SWAP.W	D4
	CLR.W	D4
	LIB	?DRSEG

	POPM.L	D2..D4
	RET

DRD0C:
	PUSHM.L	D2..D4

	LOAD.W	D2,#CLRDOT

	LOAD.L	D3,D0
	SUB.W	D3,#10
	CLR.L	D4
	LOAD.W	D4,#20
	LIB	?DRSEG

	LOAD.L	D3,D0
	SWAP.W	D3
	SUB.W	D3,#10
	SWAP.W	D3
	LOAD.W	D4,#20
	SWAP.W	D4
	CLR.W	D4
	LIB	?DRSEG

	POPM.L	D2..D4
	RET


AFCOOR:
	PUSH.L	D4

	LIB	?AFTIM
	.ASCIZ	" x="
	.EVEN
	CALL	AFD4

	SWAP.W	D4
	LIB	?AFTIM
	.ASCIZ	" y="
	.EVEN
	CALL	AFD4

	POP.L	D4
	RET

AFD4:
	PUSHM.L	D2..D4

	AND.L	D4,#H'FFFF
	TEST.W	D4
	JUMP,NC 20$
	LOAD.B	D3,#'-
	LIB	?AFCAR
	NEG.W	D4
20$:
	LOAD.W	D3,#8
	LOAD.W	D2,#2^BAFDCM
	LIB	?AFDEC

	POPM.L	D2..D4
	RET




; Textes
; ------

TXMENU0:
	.ASCIZ	""
	.ASCIZ	"Fin"

	.ASCIZ	"Suite des"
	.ASCIZ	"explications ..."

	.ASCIZ	""
	.ASCIZ	""

	.ASCIZ	""
	.ASCIZ	""

	.ASCIZ	""
	.ASCIZ	""

	.ASCIZ	""
	.ASCIZ	""


TXMENU1:
	.ASCIZ	""
	.ASCIZ	"Fin"

	.ASCIZ	""
	.ASCIZ	"Dbut du jeu"

	.ASCIZ	""
	.ASCIZ	""

	.ASCIZ	""
	.ASCIZ	""

	.ASCIZ	""
	.ASCIZ	""

	.ASCIZ	""
	.ASCIZ	""


TXMENU2:
	.ASCIZ	""
	.ASCIZ	"Fin"

	.ASCIZ	""
	.ASCIZ	""

	.ASCIZ	""
	.ASCIZ	""

	.ASCIZ	""
	.ASCIZ	""

	.ASCIZ	""
	.ASCIZ	""

	.ASCIZ	""
	.ASCIZ	"Aide"


TXMENU3:
	.ASCIZ	""
	.ASCIZ	"Fin"

	.ASCIZ	""
	.ASCIZ	"Lance la balle"

	.ASCIZ	""
	.ASCIZ	""

	.ASCIZ	""
	.ASCIZ	""

	.ASCIZ	""
	.ASCIZ	""

	.ASCIZ	""
	.ASCIZ	"Aide"


NAIMA:	.ASCIZ	"PING_AIDE.IMAGE"
NRIMA:	.ASCIZ	"PING_RAQ.IMAGE"
NMIMA:	.ASCIZ	"PING_JEU.IMAGE"
NFIMA:	.ASCIZ	"PING_FIN.IMAGE"
	.EVEN






	.END	START
