; Structure de programme de jeu pour
;  le r{seau Virtual Net de Wizcat
;     Par Zik pour Quasar CPC 17
;           Automne 1999
;
        Org &8000
        Nolist

LgInfJ  Equ 4
LgEtatJ Equ 4
LgPartieInf Equ 4

        call One
; <di, mise en place int, ei>
        call alea
; <Saisie nom>
        ld hl,mes1
        call mesg

; V{rifie que le 1 est stable
; (= pas de partie en cours)
Verif   call vnZero
        jp nc,PartieEnCours
; Timeout
        ld hl,mes2
        call mesg

; Attente du d{but d'une nouvelle
; partie d{clench{e par l'appui sur
; une touche d'un des CPC du r{seau
AttendDebPartie
        call tstline
        jr z,Cpasmoi
; Attend une touche
        halt
        call &bb09
        jr nc,attenddebpartie
; touche appuy{e
        jr Cmoi

; Une partie est d{j@ en cours,
; il faut attendre qu'elle finisse
PartieEnCours
        ld hl,mes4
        call mesg
        ; attend d'avoir un 1 stable
Attend0 call vnZero
        jr nc,attend0
        jr verif

; ** On fait d{marrer une partie **
Cmoi    call tstline
        jr z,PartieEnCours
; force la ligne @ 0 pour indiquer
; qu'on commence une partie
        call Zero

        ld hl,mes5
        call mesg
; <pr{pare les infos sur la partie>

; Attend que tout le monde soit pret
        ld hl,3000
        call vnWait

        di
        call One ; pour synchroniser
        ld hl,30
        call vnWait ; attente

; Envoi des caract{ristiques
; de la partie @ venir
        ld hl,partieinf
        ld de,lgpartieinf
        call Sndb
        jp commun

; ** On participe @ une partie **
; **    lanc{e par un autre    **
Cpasmoi ld hl,mes5
        call mesg
        di
        call vnOne ; synchronisation
        jp c,erreur

; Re\oit le bloc d'info sur la
; partie @ venir
        ld hl,partieinf
        ld de,lgpartieinf
        call Recb
        jp c,erreur ; si timeout

Commun  call Zero

; Si les donn{es ne conviennent pas
;        call One
;        ei
;        jp attenddebpartie

; Les donn{es nous conviennent...

; <Pr{pare la carte du niveau>
; <choisit une position de d{part>

        ld hl,mes6
        call mesg
        di
        call One
        call vnOne
        jp c,erreur ; si timeout

; Il faut maintenant {changer les
; donn{es des joueurs (nom, position
; de d{part, ...) et en d{duire le
; nombre de joueurs et le num{ro de
; notre joueur
        ld de,(ID)
        ld hl,infos
        ld (ptr),hl
        xor a
        ld (NbrJ),a
        ld hl,&5f3f
Dial    call tstline
        jr z,Ecoute
        dec hl
        ld a,h
        or l
        jp z,FinDial
        dec de
        ld a,d
        or e
        jr nz,Dial
; A nous de parler (DE est @ 0)
Parle   push hl
        call Zero
        ld hl,50
        call vnWait
        call One
        ld hl,30
        call vnWait ; attente
; Envoi des caract{ristiques du
; joueur (nom, pos de d{part, ...)
        ld hl,infosJ
        ld de,lginfJ
        call Sndb

        call Zero ; fini de parler

; copie des infos en m{moire
        ld hl,infosJ
        ld de,(ptr)
        ld bc,lginfJ
        ldir
; mise @ jour du pointeur
        ex de,hl
        ld de,lgetatJ
        add hl,de
        ld (ptr),hl

        ld a,(nbrJ)
        ld (noJ),a
        inc a
        ld (nbrJ),a

        call One ; lib}re la ligne
        call vnOne

        pop hl
        jp c,erreur ; si timeout
        ld de,&ffff
        jp dial

; Un autre joueur envoie ses donn{es
Ecoute  push hl
        push de
        call vnOne
        jp c,erreur ; si timeout
; Re\oit le bloc d'info du joueur
        ld hl,(ptr)
        ld de,lginfJ
        call Recb
        jp c,erreur ; si timeout

        call Zero
; Incr{mente le pointeur
        ld hl,(ptr)
        ld de,lginfJ+lgetatJ
        add hl,de
        ld (ptr),hl

        ld hl,nbrj
        inc (hl)

        call One
        call vnOne

        pop de
        pop hl
        jp c,erreur
        jp dial

; Tous les joueurs ont parl{
FinDial ld hl,&200
        call vnWait

        call Zero
        ei
        ld hl,mes7
        call mesg
        ld a,(nbrj)
        call affnbr
        ld a,(noj)
        call affnbr

; <Calculs initiaux>
; <affichage du d{cors>

        di
        call One
        call vnOnei ; sans timeout
        call zero
        ei

; *** Boucle du jeu ***
Boucle  ld hl,mes8
        call mesg
        di
        call One ; synchronisation
        call vnOne
        jp c,erreur ; si timeout
; tout le monde est au meme point

; Echange d'infos sur les joueurs
; ({tat clavier/joystick, position
; dans le niveau,...)
        ld hl,infos+lginfJ
        ld (ptr),hl
        ld a,(nbrJ)
        ld b,a
        ld c,0 ; no du joueur
Jsuiv   push bc
        ld a,(noJ)
        cp c
        jr nz,ecouteJ
ParleJ  ld hl,(ptr)
        ld de,lgetatJ
        call Sndb
        jr nextJ

EcouteJ ld hl,(ptr)
        ld de,lgetatJ
        call Recb
        jp c,erreur_ ; si timeout

NextJ   ld hl,(ptr)
        ld bc,lginfJ+lgetatJ
        add hl,bc
        ld (ptr),hl
        pop bc
        inc c
        djnz Jsuiv
; Tous les joueurs ont parl{
        ld hl,10
        call vnWait
        call Zero
        ei

; <traiter les donn{es>
; <affichages>
; <test clavier>

; si partie termin{e -> jp finpartie
; sinon              -> jp boucle

; -- la suite est pour les tests --

; affiche les {tats des joueurs
        ld a,(nbrJ)
        ld b,a
        ld hl,infos
        ld c,0
Aff_B   push bc
        ld de,lginfJ
        add hl,de
        ld de,mes_etat4
        ld bc,lgetatJ
        ldir
        pop bc
        ld a,c
        add a,&30
        ld (mes_etat3+7),a
        push bc
        push hl
        ld hl,mes_etat3
        call mesg
        pop hl
        pop bc
        inc c
        djnz aff_b

        ld hl,10000
        call vnWait ; longue attente

; place des infos al{atoires dans
; l'{tat de notre joueur
        ld a,(noJ)
        call calcadr
        ld de,lginfJ
        add hl,de
        ld de,mes_etat2
        ld b,lgetatJ
pokeJ   ld a,r
        xor b ; pour brasser un peu
        and &3f
        add a,&30
        ld (hl),a
        ld (de),a
        inc hl
        inc de
        djnz pokeJ

; affiche l'{tat choisi
        ld hl,mes_etat1
        call mesg

; test clavier
        halt
        call &bb09
        jp nc,boucle
        cp &20
        jp z,finpartie
        cp 13
        jp z,finprg
        jp boucle

; Quand une partie se termine pour
; notre joueur il faut attendre la
; fin de la partie en cours
Finpartie call One
; attend d'avoir un 1 stable
Attend1 call vnZero
        jr nc,attend1
; <afficher le nom du gagnant, ...>
        ld hl,mes9
        call mesg
        jp verif

Finprg  call One
        ret

; Data Error !
Erreur_ pop hl
Erreur  call One
        call alea

        ld hl,mes3
        call mesg
        jp partieencours

; Choisit al{atoirement un nombre
; 16 bits de 4000 @ 20383
; identifiant le joueur
Alea    ld a,r
        and &3f
        ld h,a
        ld a,r
        ld l,a
        ld bc,4000
        add hl,bc
        ld (ID),hl
        ret

; Teste l'{tat de la ligne
; Out    ;  Z si ligne @ 0
;        ; NZ si ligne @ 1
TstLine ld b,&f5
        in b,(c)
        bit 6,b
        ret

; Passe la ligne @ 1
One     ld bc,&ef80
        out (c),c
        ret

; Force la ligne @ 0 (prioritaire)
Zero    ld bc,&ef00
        out (c),c
        ret

Ptr  dw 0 ; variable temporaire
ID   dw 0 ; nb identifiant le joueur
NbrJ db 0 ; nombre de joueurs
NoJ  db 0 ; notre num{ro de joueur

; Routine; 'sndb', transmit a block
; ----------------------------------
; In  ; HL=Pointer to the data block
;       DE=Length of the data block
; Out ; A, BC, DE, HL destroyed
;
Sndb    push de
        ld a,(hl)
        inc hl
        call vnsnd
        pop de
        dec de
        ld a,d
        or e
        jr nz,sndb
        ret

; Routine; 'recb', receive a block
; ----------------------------------
; In  ; HL=Pointer to a buffer
;       DE=Length of the data block
; Out ; CY=0 --> Ok
;       CY=1 --> Timeout error
;       A, BC, DE, HL destroyed
;
Recb    push de
        call vnrec
        jr c,rec1
        ld (hl),a
        inc hl
        pop de
        dec de
        ld a,d
        or e
        jr nz,recb
        or a
        ret
Rec1    pop de
        ret

; Renvoie dans HL l'adresse des
; infos du joueur num{ro A
CalcAdr ld de,taille
        call mult
        ex de,hl
        ld hl,infos
        add hl,de
        ret

; HL=DE*A
Mult    ld b,8
        ld hl,0
Mulbouc rra
        jr nc,mulsaut
        add hl,de
Mulsaut sla e
        rl d
        djnz mulbouc
        ret

; Affiche un message @ l'ecran
; avec retour @ la ligne
Mesg    ld a,(hl)
        cp &ff
        jp z,fintxt
        cp 32
        jr c,CtrlCh
        push hl
        call &bb5a
        pop hl
CtrlCh  inc hl
        jr mesg
Fintxt  ld a,13
        call &bb5a
        ld a,10
        call &bb5a
        ret

; Affiche un chiffre de 0 @ 9
; avec retour @ la ligne
Affnbr  add a,&30
        call &bb5a
        jp fintxt

Mes1    db "Saisie du nom",255
Mes2    db "Appuyez sur une touche pour demarrer une partie",255
Mes3    db "Data error !",255
Mes4    db "Jeu deja en cours !",255
Mes5    db "Preparation du jeu",255
Mes6    db "Echange des donnees des joueurs",255
Mes7    db "Debut de la partie",255
Mes8    db "Echange des etats des joueurs",255
Mes9    db "Fin de la partie",255
Mes_etat1 db "Mon nouvel etat : "
Mes_etat2 ds lgetatJ:db 255
Mes_etat3 db "Joueur x "
Mes_etat4 ds lgetatJ:db 255

        read"vn96rout.asm" ; Pour Maxam

PartieInf ds lgpartieinf
InfosJ  ds lginfJ

Taille  Equ lginfJ+lgetatJ
NbmaxJ  Equ 4 ; non traite ds le prg
Infos   ds nbmaxJ*taille
 de jeu pour
;  le r{seau Virtual Net de Wizcat
;     Par Zik pour Quasar CPC 17
;           Automne