
;********************************************
;*** Routines pour l'affichage de sprites ***
;***  dans le mode VGA 320*200/256c.      ***
;********************************************
EMS  =1
NOEMS=0


SPRITES_ROUTINES MACRO
BX_ DW 0
PT  DW 0
 
 SPR_MEM_DECODE:
   CLI
   CLD
   LODSW 
   ADD DI,AX
   LODSW
   CMP AX,0
   JE FIN_DECODE
   MOV CX,AX
   ;*rajout
   bb:

    mov al,es:di
    mov al,ds:si
    mov es:di,al
    inc di
    inc si
   loop bb


   ;fin
  ; REP MOVSB

   JMP SPR_MEM_DECODE
  FIN_DECODE:
  STI
 RET

 MASK_SPR_MEM_DECODE:
 JMP MASK_SPR_MEM_DECODE3
  MLL DW 0
  MPP DW 0
  MXX DW 0
 MASK_SPR_MEM_DECODE3:

 
  MOV BX,20
  MUL BX 
  MOV BX,GS
  ADD AX,BX
  MOV GS,AX

  MOV AX,DI
  MOV BX,4
  MUL BX
  ADD AX,CS:MPP
  MOV CS:MXX,AX
    
 MASK_SPR_MEM_DECODE2:
   
   CLI
   CLD
   LODSW 
   ADD DI,AX
   MOV BX,4
   MUL BX
   ADD CS:MXX,AX
   LODSW
   CMP AX,0
   JE M_FIN_DECODE
   MOV CX,AX
   ADD SI,CX
   PUSH SI
   MOV SI,CS:MXX
   MASK01:
    MOV AL,[GS:SI]
    MOV [ES:DI],AL
    ADD SI,4
    INC DI
   LOOP MASK01
   MOV CS:MXX,SI
   POP SI
   JMP MASK_SPR_MEM_DECODE2
  M_FIN_DECODE:
  STI
 RET


P_TEST: 
  PUSH DS
  MOV DS,AX
  
  XOR SI,SI                 
  CLD
  LODSW                      ;Lit le nombre de sprite pour ce handle
  CMP BX,AX                  ;Si le numero demander est plus grand 
  JAE P_TEST_FIN             ;que le nombre maximal de sprites alors on sort.

  PUSH DX
  SHL BX,2
  ADD BX,2
  MOV SI,BX
  


  CLD
  LODSW
  PUSH AX
  LODSW
  MOV BX,DS
  ADD AX,BX
  MOV DS,AX
  POP SI
  
  
  LODSW
  POP DX
  
  LODSW
  MOV BX,WORD PTR CS:[PT]
  CMP BX,AX 
  JB suit_P_TEST
  MOV AL,0
  JMP P_TEST_FIN
suit_p_test:
  PUSH DX
  
  PUSH SI
  PUSH AX
  
  SHL CS:[PT],1
  ADD SI,CS:[PT]
  
  LODSW
  MOV WORD PTR CS:[PT],AX
  
  POP AX
  POP SI
  SHL AX,1
  ADD SI,AX


  LODSW
  SHR AX,1
  SUB CX,AX
  
  LODSW
  SHR AX,1
  POP DX
  SUB DX,AX

  MOV DI,CX
  MOV AX,DX
  MOV BX,20
  MUL BX 
  MOV BX,ES
  ADD AX,BX
  MOV ES,AX
  ADD DI,WORD PTR CS:[PT]
  MOV AL,ES:[DI+1]

  P_TEST_FIN:
  POP DS
 RET

 AFFICHE_SPRITE: 
  PUSH DS
  MOV DS,AX
  
  XOR SI,SI                 
  CLD
  LODSW                      ;Lit le nombre de sprite pour ce handle
  CMP BX,AX                  ;Si le numero demander est plus grand 
  JAE FIN_AFFICHE_spr        ;que le nombre maximal de sprites alors on sort.

  PUSH DX
  SHL BX,2
  ADD BX,2
  MOV SI,BX
  


  CLD
  LODSW
  PUSH AX
  LODSW
  MOV BX,DS
  ADD AX,BX
  MOV DS,AX
  POP SI
  
  LODSW

  LODSW
  SHL AX,1
  ADD SI,AX


  LODSW
  ADD AX,CS:MLL
  SHR AX,1
  SUB CX,AX
  MOV DX,CX
  AND DX,11b
  PLAN_BIT DL
  SHR CX,2
  DEC CX
  INC CS:MLL


  LODSW
  SHR AX,1
  POP DX
  SUB DX,AX



  MOV DI,CX
  MOV AX,DX
  MOV BX,5
  MUL BX 
  MOV BX,ES
  ADD AX,BX
  MOV ES,AX

  CALL SPR_MEM_DECODE
 
  FIN_AFFICHE_SPR:
  POP DS
 RET

 MASQUE_SPRITE: 
  PUSH DS
  MOV DS,AX
  
  XOR SI,SI                 
  CLD
  LODSW                      ;Lit le nombre de sprite pour ce handle
  CMP BX,AX                  ;Si le numero demander est plus grand 
  JAE M_FIN_AFFICHE_spr      ;que le nombre maximal de sprites alors on sort.

  PUSH DX
  SHL BX,2
  add bx,2
  mov SI,BX
  


  CLD
  LODSW
  PUSH AX
  LODSW
  MOV BX,DS
  ADD AX,BX
  MOV DS,AX
  POP SI
  
  LODSW

  LODSW
  SHL AX,1
  ADD SI,AX

  LODSW
  ADD AX,CS:MLL
  SHR AX,1
  SUB CX,AX
  MOV DX,CX
  AND DX,11b
  MOV CS:MPP,DX
  PLAN_BIT DL
  SHR CX,2
  DEC CX
  INC CS:MLL
 

  LODSW
  SHR AX,1
  POP DX
   SUB DX,AX
  PUSH DX
   MOV DI,CX
   MOV AX,DX
   MOV BX,5
   MUL BX 
   MOV BX,ES
   ADD AX,BX
   MOV ES,AX
  POP AX

  CALL MASK_SPR_MEM_DECODE
 
  M_FIN_AFFICHE_SPR:
  POP DS
 RET

EMS_P_TEST: 
  MOV WORD PTR CS:[BX_],BX
  PUSH DS
  PUSH DX
  PUSH CX
  PUSH AX

  MOV BX,WORD PTR CS:[EMSADD]
  POP DX
  PUSH DX
  PUSH BX
  MOV BX,0
  MOV AL,0
  MOV AH,44H
  INT 67H
  POP DS
  XOR SI,SI                 
  CLD
  LODSW                      ;Lit le nombre de sprite pour ce handle
  MOV BX,WORD PTR CS:[BX_]
  CMP BX,AX                  ;Si le numero demander est plus grand 
  JAE EMS_FIN_P_TEST     ;que le nombre maximal de sprites alors on sort.

  SHL BX,2
  add bx,2
  mov SI,BX
  
  

  XOR EBX,EBX
  XOR EAX,EAX

  CLD
  LODSW
  PUSH AX
  LODSW
  SHL EAX,4
  POP BX
  ADD EAX,EBX
  PUSH EAX
  XOR EBX,EBX
  
  MOV SI,AX
  AND SI,0011111111111111b
  
  POP EBX
  SHR EBX,14
  MOV AL,0
  POP DX
  PUSH DX
  PUSH BX
  MOV AH,44H
  INT 67H
  
  LODSW
  CMP AX,0011111111111111b
  JB PSUITESPREMS01
  CMP AX,0111111111111111b
  JB PSUITESPREMS02
  
  
  
  POP BX
  ADD BX,3
  POP DX
  MOV AL,3
  PUSH DX
  PUSH BX
  MOV AH,44H
  INT 67H

PSUITESPREMS02:   
  POP BX
  ADD BX,2
  POP DX
  MOV AL,2
  PUSH DX
  PUSH BX
  MOV AH,44H
  INT 67H

PSUITESPREMS01:   
  POP BX
  INC BX
  POP DX
  MOV AL,1
  MOV AH,44H
  INT 67H

  LODSW
  PUSH AX
  PUSH SI
  SHL CS:[PT],1
  ADD SI,CS:[PT]
  LODSW
  MOV CS:[PT],AX

  
  POP SI
  POP AX
  SHL AX,1
  ADD SI,AX



  LODSW
  SHR AX,1
  POP CX
  SUB CX,AX
  
  LODSW
  SHR AX,1
  POP DX
  SUB DX,AX



  MOV DI,CX
  MOV AX,DX
  MOV BX,20
  MUL BX 
  MOV BX,ES
  ADD AX,BX
  MOV ES,AX
  ADD DI,CS:[PT]
  MOV AL,ES:[DI+1]

  
  PUSH AX
  PUSH AX
  PUSH AX
  EMS_FIN_P_TEST:
  POP AX
  POP AX
  POP AX
  POP DS
 RET

EMSAFFICHE_SPRITE: 
  MOV WORD PTR CS:[BX_],BX
  PUSH DS
  PUSH DX
  PUSH CX
  PUSH AX
  
  MOV BX,WORD PTR CS:[EMSADD]
  
  POP DX
  PUSH DX
  PUSH BX
  MOV BX,0
  MOV AL,0
  MOV AH,44H
  INT 67H
  POP DS
  XOR SI,SI                 
  CLD
  LODSW                      ;Lit le nombre de sprite pour ce handle
  MOV BX,WORD PTR CS:[BX_]
  CMP BX,AX                  ;Si le numero demander est plus grand 
  JAE EMSFIN_AFFICHE_spr     ;que le nombre maximal de sprites alors on sort.

  SHL BX,2
  add bx,2
  mov SI,BX
  
  

  XOR EBX,EBX
  XOR EAX,EAX

  CLD
  LODSW
  PUSH AX
  LODSW
  SHL EAX,4
  POP BX
  ADD EAX,EBX
  PUSH EAX
  XOR EBX,EBX
  
  MOV SI,AX
  AND SI,0011111111111111b
  
  POP EBX
  SHR EBX,14
  MOV AL,0
  POP DX
  PUSH DX
  PUSH BX
  MOV AH,44H
  INT 67H
  
  LODSW
  CMP AX,0011111111111111b
  JB SUITESPREMS01
  CMP AX,0111111111111111b
  JB SUITESPREMS02
  
  
  
  POP BX
  ADD BX,3
  POP DX
  MOV AL,3
  PUSH DX
  PUSH BX
  MOV AH,44H
  INT 67H

SUITESPREMS02:   
  POP BX
  ADD BX,2
  POP DX
  MOV AL,2
  PUSH DX
  PUSH BX
  MOV AH,44H
  INT 67H

SUITESPREMS01:   
  POP BX
  INC BX
  POP DX
  MOV AL,1
  MOV AH,44H
  INT 67H

  LODSW
  SHL AX,1
  ADD SI,AX

  LODSW
  SHR AX,1
  POP CX
  SUB CX,AX
  
  LODSW
  SHR AX,1
  POP DX
  SUB DX,AX



  MOV DI,CX
  MOV AX,DX
  MOV BX,20
  MUL BX 
  MOV BX,ES
  ADD AX,BX
  MOV ES,AX

  CALL SPR_MEM_DECODE
  PUSH AX
  PUSH AX
  PUSH AX
  EMSFIN_AFFICHE_SPR:
  POP AX
  POP AX
  POP AX
  POP DS
 RET

MASK_EMS_SPRITE: 
  MOV WORD PTR CS:[BX_],BX
  PUSH DS
  PUSH DX
  PUSH CX
  PUSH AX
  
  MOV BX,WORD PTR CS:[EMSADD]
  
  POP DX
  PUSH DX
  PUSH BX
  MOV BX,0
  MOV AL,0
  MOV AH,44H
  INT 67H

  POP DS
  XOR SI,SI                 
  CLD
  LODSW                      ;Lit le nombre de sprite pour ce handle
  MOV BX,WORD PTR CS:[BX_]
  CMP BX,AX                  ;Si le numero demander est plus grand 
  JAE M_EMSFIN_AFFICHE_spr        ;que le nombre maximal de sprites alors on sort.

  SHL BX,2
  add bx,2
  mov SI,BX
  
  

  XOR EBX,EBX
  XOR EAX,EAX

  CLD
  LODSW
  PUSH AX
  LODSW
  SHL EAX,4
  POP BX
  ADD EAX,EBX
  PUSH EAX
  XOR EBX,EBX
  MOV SI,AX
  AND SI,0011111111111111b
  
  POP EBX
  SHR EBX,14
  MOV AL,0
  POP DX
  PUSH DX
  PUSH BX
  MOV AH,44H
  INT 67H
  
  LODSW
  CMP AX,0011111111111111b
  JB M_SUITESPREMS01
  CMP AX,0111111111111111b
  JB M_SUITESPREMS02
  
  
  
  POP BX
  INC BX
  POP DX
  MOV AL,1
  PUSH DX
  PUSH BX
  MOV AH,44H
  INT 67H

M_SUITESPREMS02:   
  POP BX
  INC BX
  POP DX
  MOV AL,1
  PUSH DX
  PUSH BX
  MOV AH,44H
  INT 67H

M_SUITESPREMS01:   
  POP BX
  INC BX
  POP DX
  MOV AL,1
  MOV AH,44H
  INT 67H




  LODSW
  SHL AX,1
  ADD SI,AX

  
  LODSW
  SHR AX,1
  POP CX
  SUB CX,AX
  
  LODSW
  SHR AX,1
  POP DX
  SUB DX,AX


  PUSH DX
  MOV DI,CX
  MOV AX,DX
  MOV BX,20
  MUL BX 
  MOV BX,ES
  ADD AX,BX
  MOV ES,AX
  POP DX
  CALL MASK_SPR_MEM_DECODE
  PUSH AX
  PUSH AX
  PUSH AX
  M_EMSFIN_AFFICHE_SPR:
  POP AX
  POP AX
  POP AX
  POP DS
 RET

 LOADSPRITE:  
  JMP suiteloadsprite
  si_ DW 0
  DX_  DW 0

suiteloadsprite:
  MOV DX_,DX
  XOR CX,CX
  MOV AH,4EH
  INT 21H

  MOV EBX,TAILLE
  MOV EAX,EBX
  SHR EAX,16
  ADD EBX,EAX
  PUSH EBX                 ;Empile la taille du fichier.
  ADD EBX,16
  SHR EBX,4
  MOV AH,048H
  INT 21H
  MOV SI,CS:[SI_]
  MOV WORD PTR DS:[SI],AX

  MOV DX,DX_
  MOV AL,0
  MOV AH,03DH
  INT 21H
  POP ECX               ;Depile la taille du fichier.
  PUSH AX               ;Empile le handle du fichier ouvert.
  PUSH DS               ;Empile DS.
  MOV BX,AX

  MOV SI,CS:[SI_]
  MOV AX,WORD PTR DS:[SI]
  SHL EAX,4                        ;Initialise la position en memoire.
  MOV EDX,EAX
  
  PUSH CX
  SHR ECX,16 
  CMP CX,0
  JE FINloadsprite

loadimg01:
  PUSH CX
  PUSH EDX
  MOV AX,DX
  AND AX,00001111B
  SHR EDX,4
  MOV DS,DX
  MOV DX,AX
  MOV CX,0FFFFH
  MOV AH,03FH
  INT 21H
  
  POP EDX
  ADD EDX,65535
  POP CX
 loop loadimg01

FINloadsprite:  
  MOV AX,DX
  AND AX,00001111B
  SHR EDX,4
  MOV DS,DX
  MOV DX,AX
  POP CX
  MOV AH,03FH
  INT 21H




  POP DS                ;Depile DS.
  POP BX                ;Depile le handle du fichier a fermer.
  MOV AH,03EH
  INT 21H               ;Ferme le fichier.
 RET

EMSLOADSPRITE:  
  JMP EMSsuiteloadsprite
  EMSsi_ DW 0
  EMSDX_  DW 0
  EMSADD  DW 0
  PAGEl   DW 0

EMSsuiteloadsprite:
  MOV EMSDX_,DX
  XOR CX,CX
  MOV AH,4EH
  INT 21H

  MOV EBX,TAILLE
  PUSH EBX
  MOV AH,41H
  INT 67H
  MOV CS:[EMSADD],BX
  POP EBX
  PUSH EBX
  SHR EBX,14
  ADD BX,1
  MOV AH,43H
  INT 67H
  MOV SI,EMSSI_
  MOV DS:SI,DX

  MOV DX,EMSDX_
  MOV AL,0
  MOV AH,03DH
  INT 21H
  POP ECX               ;Depile la taille du fichier.
  PUSH AX               ;Empile le handle du fichier ouvert.
  MOV BX,AX
  PUSH DS               ;Empile DS.
  MOV AX,DS
  MOV GS,AX
  
  SHR ECX,14
  ADD CX,1
  MOV CS:[PAGEl],0

EMSloadsp:
  PUSH CX
  
  PUSH BX
  
  MOV SI,EMSSI_
  MOV DX,GS:SI
  MOV BX,CS:[PAGEl]
  MOV AL,0
  MOV AH,44H
  INT 67H
  
  POP BX

  MOV AX,CS:[EMSADD]
  MOV DS,AX
  XOR DX,DX
  MOV CX,0100000000000000B
  MOV AH,03FH
  INT 21H
  
  INC CS:[PAGEl]
  POP CX
LOOP EMSloadsp

  POP DS                ;Depile DS.
  POP BX                ;Depile le handle du fichier a fermer.
  MOV AH,03EH
  INT 21H               ;Ferme le fichier.
 RET

ENDM


DECODE_SPRITE MACRO  SEGdep,OFFdep,SEGarr,OFFarr
  PUSH DS
  MOV AX,SEGdep
  MOV SI,OFFdep
  MOV BX,SEGarr
  MOV DI,OFFARR
  MOV DS,AX
  MOV ES,BX
  CALL SPR_MEM_DECODE
  POP DS
ENDM

LOAD_SPRITE MACRO NOMfich,Handle
  LEA DX,NOMfich
  MOV CS:[SI_],OFFSET Handle
  CALL LOADsprite
ENDM

LOAD_SPRITE_EMS MACRO NOMfich,Handle
  LEA DX,NOMfich
  MOV CS:[EMSSI_],OFFSET Handle
  CALL EMSLOADsprite
ENDM


PUT_SPRITE_EMS MACRO NOM,NUMERO,X,Y,PAGE
  MOV AX,PAGE
  MOV ES,AX
  MOV AX,NOM
  MOV BX,NUMERO
  MOV CX,X
  MOV DX,Y
  CALL EMSAFFICHE_SPRITE 
ENDM

POINT_TEST_EMS MACRO NOM,NUMERO,X,Y,PAGE,NUM_P
  MOV AX,PAGE
  MOV ES,AX
  MOV AX,NOM
  MOV BX,NUMERO
  MOV CX,X
  MOV DX,Y
  MOV CS:[PT],NUM_P
  CALL EMS_P_TEST 
ENDM

POINT_TEST MACRO NOM,NUMERO,X,Y,PAGE,NUM_P
 MOV AX,PAGE
 MOV ES,AX
 MOV AX,NOM
 MOV BX,NUMERO
 MOV CX,X
 MOV DX,Y
 MOV CS:[PT],NUM_P
 CALL P_TEST
ENDM


;******************************************
;* Affiche un sprite sur une page(adresse)*
;*   entre: NOM: handle du sprite         *
;*       NUMERO: numero du sprite         *
;*          X,Y: Position du sprite       *
;*         PAGE: Page ou il est affiche   *
;******************************************

PUT_SPRITE MACRO NOM,NUMERO,X,Y,PAGE

  
  XOR AX,AX
  MOV CS:MLL,AX

  MOV AX,PAGE                 ;de la sous routine d'affichage.
  MOV ES,AX
  MOV AX,NOM
  MOV BX,NUMERO
  MOV CX,X
  MOV DX,Y
  PUSHA 
  PUSH ES
  CALL AFFICHE_SPRITE          ;Appele  la sous routine d'affichage.
  POP ES
  POPA

  INC CX
  INC BX
  PUSHA
  PUSH ES
  CALL AFFICHE_SPRITE
  POP ES
  POPA

  INC CX
  INC BX
  PUSHA
  PUSH ES
  CALL AFFICHE_SPRITE
  POP ES
  POPA

  INC CX
  INC BX
  CALL AFFICHE_SPRITE
  

ENDM


;*****************************************
;* Masque un sprite.                     *
;* entree NOM:handle du sprite           *
;*        NUMERO:numero du sprite        *
;*        X,Y:position                   *
;*        PAGE:page d'affichage          *
;*        PAGEmask:Page de mask          *
;*****************************************

MASK_SPRITE MACRO NOM,NUMERO,X,Y,PAGE,PAGEMASK
  XOR AX,AX
  MOV CS:MLL,AX

  MOV CX,X                        ;sauvegarde la pos x en cx.

  MOV AX,PAGEMASK                  ;sauve la pagemask en GS
  MOV GS,AX
  MOV AX,PAGE                      ;Met la valeur de la page en ES
  MOV ES,AX
  MOV AX,NOM                       ;AX=handle du sprite.
  MOV BX,NUMERO                    ;BX=numero du spr.
  MOV DX,Y                         ;DX=Pos y.
  PUSHA
  PUSH ES
  PUSH GS
  CALL MASQUE_SPRITE               ;Appelle la sous routine qui gere les
  POP GS
  POP ES
  POPA
                                   ;differentes info du handle.
  INC CX
  INC BX
  PUSHA
  PUSH ES
  PUSH GS 
  CALL MASQUE_SPRITE
  POP GS
  POP ES
  POPA

  INC CX
  INC BX
  PUSHA
  PUSH ES
  PUSH GS 
  CALL MASQUE_SPRITE
  POP GS
  POP ES
  POPA

  INC CX
  INC BX
  CALL MASQUE_SPRITE
ENDM


MASK_SPRITE_EMS MACRO NOM,NUMERO,X,Y,PAGE,PAGEMASK

  MOV AX,X
  MOV BX,4
  XOR DX,DX
  DIV BX
  PLAN_BIT DL
  MOV CX,AX

  MOV AX,PAGEMASK
  MOV GS,AX
  MOV AX,PAGE
  MOV ES,AX
  MOV AX,NOM
  MOV BX,NUMERO
  MOV DX,Y
  CALL MASK_EMS_SPRITE 

  MOV AX,X
  INC AX
  MOV BX,4
  XOR DX,DX
  DIV BX
  PLAN_BIT DL
  MOV CX,AX

  MOV AX,PAGEMASK
  MOV GS,AX
  MOV AX,PAGE
  MOV ES,AX
  MOV AX,NOM
  MOV BX,NUMERO
  INC BX
  MOV DX,Y
  CALL MASK_EMS_SPRITE 

  MOV AX,X
  ADD AX,2
  MOV BX,4
  XOR DX,DX
  DIV BX
  PLAN_BIT DL
  MOV CX,AX

  MOV AX,PAGEMASK
  MOV GS,AX
  MOV AX,PAGE
  MOV ES,AX
  MOV AX,NOM
  MOV BX,NUMERO
  ADD BX,2
  MOV DX,Y
  CALL MASK_EMS_SPRITE 

  MOV AX,X
  ADD AX,3
  MOV BX,4
  XOR DX,DX
  DIV BX
  PLAN_BIT DL
  MOV CX,AX

  MOV AX,PAGEMASK
  MOV GS,AX
  MOV AX,PAGE
  MOV ES,AX
  MOV AX,NOM
  MOV BX,NUMERO
  ADD BX,3
  MOV DX,Y
  CALL MASK_EMS_SPRITE 

ENDM

DETRUIT_SPRITE_EMS MACRO NOM
 MOV AH,45H
 MOV DX,NOM
 INT 67H
ENDM

DETRUIT_SPRITE MACRO NOM
 MOV AX,NOM
 MOV ES,AX
 MOV AH,49H
 INT 21H
ENDM
  




