// Taille maxi. pour gerer le dessin d'une bande: Par exemple 4 -> 3 points et 1 espace
TAILLEBANDE EQU 4

initecran:

        lda        #21
        jsr  GRAPHICS
 
	// Initialisation des compteurs
	lda	#0
	sta 	Sens 
	lda     #40
	sta 	centre
	// Initialisation variables dessin route
	lda	levDrwCptG
	sta 	DrwCptG	// Taille de la pelouse a gauche de la route
	lda	levDrwCptD
	sta 	DrwCptD 	// Taille de la pelouse a droite de la route
	lda	levTailleRoute	
	sta 	TailleRoute // Taille de la route
	lda	#0
	sta 	TailleMem // J'ai oublie

	// Initialisation pile centre
	ldx	#55
	lda	#0
bclinitpilecentre:
	sta	bpilecentre,x
	dex
	cpx	#255
	bne bclinitpilecentre
	
        // Initialisation des pointeurs sur ecrans logique et physique
        lda        560
        sta        $e6
        lda        561
        sta        $e7
      
// Recuperation de l'adresse memoire de l'ecran dans la DPLIST  
        ldy        #4
        
        lda        ($e6),y
        sta        physique
        sta        logique
        
        iny
        lda        ($e6),y
        sta        physique+1
        sec
        sbc        #10
        sta        logique+1
                                                
// Preparation de l'ecran
        lda        #0
        sta        712

        lda        560
        sta        $e6
        lda        561
        sta        $e7
      
        ldy        #6
        lda        #6
        sta        ($e6),y   // Mode texte
        iny
        ora        #128
        sta        ($e6),y   // Mode texte

        ldy        #51
        lda        ($e6),y
        ora        #128
        sta        ($e6),y

        jsr INITDLI          // Lancer l'interruption DLI
        
        lda        88
        adc        #24
        sta        $e6
        lda        89
        adc        #0
        sta        $e7

        lda        #coucou&255
        sta        $e8
        lda        #coucou/256
        sta        $e9

        ldy        #0
bclaff:
        lda        ($e8),y
        cmp        #0
        beq finaff
        sta        ($e6),y
        iny 
        jmp bclaff

finaff  
        jsr        copierphylog
        rts

copierphylog:

        ldx        #4
        lda        physique
        sta        $e6
        lda        physique+1
        sta        $e7
        lda        logique
        sta        $e8
        lda        logique+1
        sta        $e9        
bclphylo:
        ldy        #255

        lda        ($e6),y
        sta        ($e8),y
   
bclphylo1:
        dey
        lda        ($e6),y
        sta        ($e8),y
        cpy        #0
        bne bclphylo1

        dex
        cpx        #0
        beq fbclphylo

        lda        $e7
        clc
        adc        #1
        sta        $e7

        lda        $e9
        clc
        adc        #1
        sta        $e9
        jmp bclphylo
fbclphylo:
        ldy        #172

        lda        ($e6),y
        sta        ($e8),y
   
bclphylo1b:
        dey
        lda        ($e6),y
        sta        ($e8),y
        cpy        #0
        bne bclphylo1b

        rts

/********************************************************************/
/* Cette procedure positionne la variable changepage a 1            */
/* Cette variable etant traitee dans notre interruption VBI         */
/* Ce qui permettra de permuter l'ecran logique et l'ecran physique */
/* L'interruption VBI repositionne ensuite la variable a 0 lorsque  */
/* le swapping est fait, d'ou la boucle d'attente ensuite           */
/* Cette procedure ne rendant la main que lorsque le swapping est   */
/* termine, cela evite d'avoir un  recalcul sur l'ecran physique    */
/* et donc d'avoir un effet de scintillement			    */
/********************************************************************/
changelapage:
        lda        #1
        sta        changepage
waitpage:
        lda        changepage
        cmp        #0
        bne waitpage
        rts

/********************************************************************/
/* Attendre une VBI						    */
/********************************************************************/
SynchroWaitVBI:
        lda        #1
        sta        syncVBI 
syncwaitVBI:
        lda        syncVBI 
        cmp        #0
        bne syncwaitVBI
        rts

/****************************************************************************************************************************************/
/* Nous allons faire un scrolling vers le bas												*/
/* Pour cela, nous allons lire les donnees de l'ecran physique et les recopiers dans l'ecran logique					*/
/* cela va eviter le scintillement !													*/
/* Il restera ensuite a echanger les deux ecrans pour voir le resultat ! Cet etape n'etant pas faite ici, ce n'est pas le but !		*/
/* La lecture devra debuter sur l'avant derniere ligne de l'ecran physique pour etre copier sur la derniere de l'ecran logique		*/
/* Il suffira ensuite de remonter de ligne en ligne											*/
/* Petit probleme, l'ecran faisant plus de 255 octets, nous allons donc devoir travailler sur 3 pages de 255 et terminer avec 72 octets */
/****************************************************************************************************************************************/
scrolllog:

        ldx        #3 // On se positionne sur la troisieme (et derniere) page de notre ecran
bclscroll:
        clc
        lda        physique   // Maj des pointeurs ecrans physique 
        adc        #152
        sta        $e6

        clc
        lda        logique    // et logique
        adc        #172
        sta        $e8        

        clc
        txa
        adc        logique+1  // page logique
        sta        $e9

        clc
        txa
        adc        physique+1 // page physique
        sta        $e7
   
        ldy        #255       // Dans une page, il y a 256 points
bclscroll1:
        lda        ($e6),y    // Transfert !
        sta        ($e8),y
        dey                   // Avons nous traiter les 255 octets ?
        cpy        #0
        bne bclscroll1

// jointure entre 2 pages
        clc                   // Ici, il faut maintenant faire le transfert entre la derniere ligne de la page precedente
        lda        physique   // sur la premiere ligne de la page en cours de trt
        adc        #132
        sta        $e6

        clc
        lda        logique
        adc        #152
        sta        $e8        

        ldy        #20

bclscroll1b:                  // Transfert de 20 octets (1 ligne = 20 octets !)
        lda        ($e6),y
        sta        ($e8),y
        dey
        cpy        #0
        bne bclscroll1b
        lda        ($e6),y
        sta        ($e8),y

        dex
        cpx        #0         // Avons nous traiter les 3 pages a 255 octets ?
        bne bclscroll
      
        lda        physique+1 // Oui, il reste alors la page avec 72 octets
        sta        $e7

        lda        logique+1
        sta        $e9

        ldy        #255
bclscroll2:
        lda        ($e6),y
        sta        ($e8),y
        dey
        cpy        #183      // 255 - 183 = 72 octets
        bne bclscroll2
 
finscrolllog:
        rts  

initdraw:
	lda	#0
	sta	desPont
	sta	cptPont
	lda	#3
	sta	pilier
	rts

/**************************************************************************************************/
/* Cette fonction a pour but de dessiner la route sur la premiere ligne de l'ecran reserve au jeu */
/**************************************************************************************************/
drawline:
	lda	   desPont
	cmp	   #0
	beq drawroute
	jmp drawpont

drawroute:
	ldx	cptPont
	cpx	#100 // Il faut que le compteur soit a 100 avant de penser a redessiner un pont
	beq RandomPont
	inx
	stx	cptPont
	jmp drawrouteok

RandomPont: // Voyons maintenant si nous allons ou non dessiner un pont la prochaine fois
	lda	53770
	cmp	#1
	bne drawrouteok
	ldx	#0
	stx	cptPont
	ldx	#1
	stx	desPont // Prochain coup, dessiner un pont
drawrouteok:	
        ldy        #60	// Index pour etre sur la premiere ligne de la zone de jeu

        lda        logique    // initialisation d'un pointeur sur l'ecran logique
        sta        $e8    

        lda        logique+1
        sta        $e9

	ldx	   DrwCptG    // Compteur pour dessiner l'herbe a gauche de la route
	cpx	   #0
	beq	   FinbcldrawlinG
bcldrawlineG:
        lda        #170
        sta        ($e8),y
	dex	
	iny
	cpx	#0
	bne bcldrawlineG
FinbcldrawlinG:
// Bordure de gauche, cad limite entre l'herbe et la route
	ldx	PosBd	// Index sur la bordure a utiliser
	lda	bg1,x   // Adresse, indexe par x, donne le dessin de la bordure
	sta	($e8),y
	iny

// Maintenant, on dessine la route, comme nous utilisons la couleur de fond, qui est grise a c'est endroit, on efface sur la route
	ldx	TailleRoute
	lda	#0
EffaceRoute:
        sta        ($e8),y
	dex	
	iny
	cpx	#0
	bne EffaceRoute


// Bordure de droite // limite entre la route et l'herbe
	ldx	PosBd	// Index sur la bordure a utiliser
	lda	bd1,x   // Adresse, indexe par x, donne le dessin de la bordure
	sta	($e8),y
	iny

	ldx	   DrwCptD // Puis dessin de l'herbe
	cpx	   #0
	beq	   FinbcldrawlinD		
bcldrawlineD:
        lda        #170
        sta        ($e8),y
	dex	
	iny
	cpx	#0
	bne bcldrawlineD

FinbcldrawlinD:
// Calcul de la prochaine bordure
	lda	53770
	cmp	#0
	bmi finDrawBordurecourt
	
	and	#1	// La route tourne a gauche ou a droite ???
	cmp	#0
	bne	calcDroite

	lda	Sens
	cmp	#0
	bne VAutreCtrlG
	lda	#255
	sta	Sens
	jmp	VAgauche
finDrawBordurecourt:
	lda	#0
	sta	Sens
	jmp  finDrawBordure

VAutreCtrlG:
	cmp	#255
	beq	VAgauche

	lda	#0
	sta	Sens

VAgauche:
	clc		// A gauche !
	lda	PosBd
	adc	#1	
	cmp	#4	// Avons nous fait les 4 bordures possible ??? (cad 4 deplacement a gauche, nous passons donc sur l'octet precedent puisque 4 points ds un octet)
	bne CalcOkBord
	
// Sommes nous sur le bord de l'ecran ?
	lda	DrwCptG
	cmp	#1
	bne decrouteG
	lda	#0
	sta	Sens
	lda	#3 // On reste la ou l'on ait, pas de decrementation !!!
	jmp CalcOkBord

decrouteG:	
// On decremente la route sur la gauche, toutes les bordures sont faites

	ldx	DrwCptG
	dex	
	stx	DrwCptG
	ldx	DrwCptD
	inx
	stx	DrwCptD

	lda	#0

	jmp CalcOkBord

// La route tourne a droite
calcDroite:
	lda	Sens
	cmp	#0
	bne VAutrCtrlD
	lda	#1
	sta	Sens
	jmp	VAdroite
VAutrCtrlD:
	cmp	#1
	beq	VAdroite

	lda	#0
	sta	Sens

VAdroite:
	sec
	lda	PosBd
	sbc	#1	
	cmp	#0	// Les 4 bordures de droites sont faites (meme commentaire que pour la bordure de gauche...)
	bpl CalcOkBord

// Somme nous sur le bord de l'ecran ?
	clc
	adc	DrwCptG // Taille Herbe gauche
	adc	TailleRoute // Taille de la route
	adc	#2 // Les bordures
	cmp	#19
	bpl DrawrienFaire
	jmp decrouteD
DrawrienFaire:
	lda	#0
	sta	Sens
	lda	#0 // On reste la ou l'on ait, pas d'incrementation !!!
	jmp CalcOkBord

decrouteD:	
// On incremente la route sur la droite toutes les bordures sont faites
	ldx	DrwCptG
	inx	
	stx	DrwCptG
	ldx	DrwCptD
	dex
	stx	DrwCptD
			
	lda	#3

CalcOkBord:
	sta	PosBd
	
finDrawBordure:	
        rts

/*************************************************************/
/* Cette procedure permet de calculer le centre de la route  */
/* nouvellement dessinee				     */
/* Ce centre devant permettre un positionnement des voitures */
/* gerees par l'ordinateur				     */
/*************************************************************/

calccentre:
	ldx DrwCptG
	inx
	txa
	asl
	asl
	sta	centre /* bord de la route A 4 point pres... */
	lda	TailleRoute
	asl
/*	asl
	lsr	/* division par 2 pour connaitre le milieu */*/
	clc
	adc	centre /* On ajoute la taille de la route / 2 et nous avons le centre */
	sta	centre	 
pilecentre:

	lda	centre
	sta     bpilecentre

/*************************************************************/
/* Maintenant que le centre est calcule, stockage dans une   */
/* pile de donnees qui contiendra tous les centres des lignes*/
/* de la route precedemment dessinee et encore visible       */
/*************************************************************/
	
	ldx	#55
desccentre:
	lda     bpilecentre,x
	inx	
	sta	bpilecentre,x
	dex
	dex
	cpx	#255
	bne desccentre

	rts

coucou        db 'vroom',64,'v',81,78,80,80,0

changepage    	db 1 // Utilise pour attendre synchro VBI avant de faire swap logique physique
syncVBI  	db 0 // Utilise pour une synchro VBI simple

// Taille de la pelouse a gauche de la route
DrwCptG		db 5
// Taille de la pelouse a droite de la route
DrwCptD		db 6

// Taille de la route
TailleRoute	db 7
TailleMem 	db 0

// Indique s'il faut dessiner le pont ou la route
desPont         db 1
// Compteur avant d'envisager de redessiner un pont
cptPont		db 0
// Longueur du pont en cours
longPont        db 0
pilier		db 3
// Index sur les bordures de la route
PosBd		db 0
Sens		db 0 // 0 tout droit, -1 a gauche, 1 a droite
centre		db 40
// Dessin des bordures gauches herbe ...
// Avec bande jaune
bg1	db 169,164,144,64  

// Dessin des bordures droites herbe ...
// avec bande jaune
bd1	db 1,6,26,106
bpilecentre bs 55 // Valeur appro, j'ai pas fait l'effort de compter
	   db 0
		db 0
		db 0 // Pour eviter un ecrasement memoire avec le code qui suit
