home *** CD-ROM | disk | FTP | other *** search
/ PC Interdit / pc-interdit.iso / graph / sprites.pas < prev    next >
Pascal/Delphi Source File  |  1994-10-17  |  11KB  |  248 lines

  1. Unit Sprites;
  2.  
  3. Interface
  4.  
  5. Type SpriteTyp=Record  {structure d'un bloc de données décrivant un sprite}
  6.   Adr:Pointer;         {pointe sur les données graphiques }
  7.   dtx,dty:Word;        {largeur et hauteur en pixels }
  8.   px,py,               {position courante, facultatif *}
  9.   sx,sy:Integer;       {vitesse courante, facultatif *}
  10. End;
  11. {* : facultatif veut dire que les routines GetSprite et PutSprite n'utilisent
  12. pas ces variables qui ne servent qu'à faciliter une gestion par le programme
  13. principal }
  14.  
  15. Procedure GetSprite(Ofs,dtx,dty:Word;var dSprite:SpriteTyp);
  16. {lit un sprite de largeur dtx, de hauteur dty, à l'offset ofs de vscreen,
  17.  dSprite est l'enregistrement qui va mémoriser le sprite}
  18.  
  19. Procedure PutSprite(pg_ofs,x,y:Integer;sSprite:spritetyp);
  20. {copie un sprite de la mémoire centrale (situation et taille dans sSprite)
  21.  vers la mémoire d'écran en page pg et coordonnées (x,y}
  22.  
  23.  
  24. Implementation
  25. Uses ModeXLib;
  26.  
  27. Var i:Word;
  28.  
  29. Procedure GetSprite;
  30. Var ppp:Array[0..3] of Byte; {table avec le nombre de pixels à copier par plan }
  31.     Skip:word;               {nombre d'octets à sauter}
  32.     Plane_Count:Word;        {nombre de plans déjà copiés }
  33. Begin
  34.   GetMem(dSprite.adr,dtx*dty); {alloue de la mémoire }
  35.   dSprite.dtx:=dtx;            {prend note de la largeur et de la hauteur }
  36.   dSprite.dty:=dty;            {dans l'enregistrement du sprite }
  37.  
  38.   i:=dtx shr 2;                {nombre de groupes de 4 octets}
  39.   ppp[0]:=i;ppp[1]:=i;         {correspond au nombre minimum d'octets à copier }
  40.   ppp[2]:=i;ppp[3]:=i;
  41.   For i:=1 to dtx and 3 do   {mémorise en ppp les pixels restants  }
  42.     Inc(ppp[(i-1) and 3]);   {ajoute les pixels en commençant par le plan de début}
  43.   Plane_Count:=4;            {copie 4 plans }
  44. asm
  45.   push ds
  46.   mov di,word ptr dSprite  {charge d'abord un pointeur sur le bloc de données}
  47.   les di,[di]              {es:di va pointer sur les données graphiques}
  48.   lea bx,ppp               {bx référence le tableau ppp}
  49.  
  50.   lds si,vscreen      {charge un pointeur sur l'écran}
  51.    add Ofs,si         {ajoute l'offset des données du sprite proprement dites}
  52. @lcopy_plane:         {boucle des plans}
  53.   mov si,ofs          {si reçoit l'adresse de début des données du sprite }
  54.   mov dx,dty          {le compteur d'ordonnées reçoit le nombre de lignes}
  55.  
  56.   xor ah,ah           {efface ah}
  57.   mov al,ss:[bx]      {charge en al l'élément courant de ppp}
  58.   shl ax,2            {on déplace des groupes de 4 octets}
  59.   sub ax,320          {calcule la différence par rapport à 320}
  60.   neg ax              {convertit ax-320 en 320-ax }
  61.   mov skip,ax         {sauvegarde le résultat en Skip }
  62.  
  63. @lcopy_y:             {boucle des lignes }
  64.   mov cl,ss:[bx]      {tire la largeur du tableau ppp }
  65. @lcopy_x:             {boucle des pixels }
  66.   movsb               {copie un octet }
  67.   add si,3            {point suivant dans le même plan }
  68.   dec cl              {copie tous les points de la ligne }
  69.   jne @lcopy_x
  70.  
  71.   add si,skip         {passe à la ligne suivante }
  72.   dec dx              {copie toutes les lignes }
  73.   jne @lcopy_y
  74.  
  75.   inc bx              {pointe sur l'élément suivant de ppp }
  76.   inc ofs             {se positionne sur le nouveau début de plan }
  77.   dec plane_count     {copie tous les plans }
  78.   jne @lcopy_plane
  79.  
  80.   pop ds
  81. End;
  82. End;
  83.  
  84. Procedure PutSprite;
  85. var plane_count,              {nombre de plans déjà copiés }
  86.     masqueplan:Byte;          {masque Write-Plane dans le registre 2 du TS }
  87.     Skip,                     {nombre d'octets à sauter }
  88.     ofs,                      {offset courant dans la mémoire d'écran }
  89.     plane,                    {numéro du plan courant }
  90.     Largeur,                  {largeur en octets à copier dans une ligne }
  91.     dty:Word;                 {hauteur }
  92.     source:Pointer;     {pointe sur les données graphiques lorsque ds varie }
  93.     clip_lt, clip_rt:integer; {nombre de pixels restant à droite et à gauche }
  94.     clipact_lt,               {nombre d'octets restants }
  95.     clipact_rt,               {pour le plan courant }
  96.     clip_dn,clip_up:Word;     {nombre de lignes restant en haut et en bas }
  97.  
  98.     ppp:Array[0..3] of Byte;  {nombre de pixels par plan }
  99.     cpp:Array[0..3] of Byte;  {nombre d'octets restants par plan }
  100.  
  101. Begin
  102.   if (x > 319) or               {pas de dessin }
  103.   (x+sSprite.dtx < 0) or        {sprite en dehors de l'écran ?}
  104.   (y > 199) or
  105.   (y+sSprite.dty < 0) then exit;
  106.   clip_rt:=0;                   {normalement pas de clipping }
  107.   clip_lt:=0;                   {-> toutes les variables de clipping à 0 }
  108.   clip_dn:=0;
  109.   clip_up:=0;
  110.   clipact_rt:=0;
  111.   clipact_lt:=0;
  112.    with sSprite do begin
  113.     if y+dty > 200 then begin  {premier cas de clipping : en bas}
  114.       clip_dn:=(y+dty-200);    {nombre de lignes restantes }
  115.       dty:=200-y;              {réduit la hauteur du sprite }
  116.     End;
  117.     if y<0 then begin          {deuxième cas de clipping: en haut}
  118.       clip_up:=-y;             {nombre de lignes restantes }
  119.       dty:=dty+y;              {réduit la hauteur du spr }
  120.       y:=0;          {ordonnée de départ nulle, au bord supérieur de l'écran }
  121.     End;
  122.     if x+dtx > 320 then begin   {troisième cas de clipping : à droite }
  123.       clip_rt:=x+dtx-320;       {pixels restants }
  124.       dtx:=320-x;               {réduit la largeur }
  125.     End;
  126.     if x<0 then begin           {quatrième cas de clipping : à gauche }
  127.       clip_lt:=-x;              { nombre de pixels restants }
  128.       plane:=4-(clip_lt mod 4); {nouveau plan de début pour la colonne 0 }
  129.       plane:=plane and 3;       {ramène à l'intervalle 0..3 }
  130.       ofs:=pg_ofs+80*y+((x+1) div 4) - 1;  {Ofs sur groupe de 4 octets }
  131.       x:=0;                                {colonne de début }
  132.     End Else Begin                         {à droite pas de clipping?}
  133.       plane:=x mod 4;                    {alors calcul conventionnel du plan }
  134.       ofs:=pg_ofs+80*y+(x div 4);        {et de l'offset }
  135.     End;
  136.   End;
  137.   Source:=sSprite.adr;         {mémorise pointeur sur les données graphiques }
  138.   dty:=sSprite.dty;            {et hauteur dans variables locales }
  139.   Largeur:=0;                  {initialise largeur et Skip }
  140.   Skip:=0;
  141.  
  142.   i:=sSprite.dtx shr 2;      {nombre de groupes de 4 octets complets}
  143.   ppp[0]:=i;ppp[1]:=i;       {correspond au nombre minimum d'octets à copier }
  144.   ppp[2]:=i;ppp[3]:=i;
  145.   For i:=1 to sSprite.dtx and 3 do{mémorise en ppp les pixels restants }
  146.     Inc(ppp[(plane+i - 1) and 3]);{ajoute les pixels en commençant par le plan de début }
  147.  
  148.   i:=(clip_lt+clip_rt) shr 2;
  149.   cpp[0]:=i;cpp[1]:=i;          {valeurs par défaut du clipping}
  150.   cpp[2]:=i;cpp[3]:=i;
  151.   For i:=1 to clip_rt and 3 do  {si clipping à droite }
  152.     Inc(cpp[i-1]);              {enregistre le nombre dans les plans }
  153.   For i:=1 to clip_lt and 3 do  {si clipping à gauche }
  154.     Inc(cpp[4-i]);              {enregistre le nombre dans les plans }
  155.  
  156. asm
  157.   mov dx,3ceh                   {met le registre 5 du GDC (GDC Mode)}
  158.   mov ax,4005h                  {en mode Write 0 }
  159.   out dx,ax
  160.   push ds                       {sauve ds}
  161.   mov ax,0a000h                 {charge le segment de destination (VGA) }
  162.   mov es,ax
  163.  
  164.   lds si,source       {ds:si va pointer sur la source (données graphiques ) }
  165.   mov cx,plane        {masque de plan de départ }
  166.   mov ax,1            {décale le bit 0 vers la gauche }
  167.   shl ax,cl
  168.   mov masqueplan,al           {sauve le masque }
  169.   shl al,4                    {le reporte dans le quartet supérieur }
  170.   or masqueplan,al
  171.   mov plane_count,4          {4 plans à copier }
  172. @lplane:                     {boucle des plans }
  173.   mov cl,byte ptr plane      {charge le plan courant }
  174.   mov di,cx                  {en di}
  175.   mov cl,byte ptr ppp[di]    {charge le nombre ppp corrrespondant en cx }
  176.   mov byte ptr Largeur,cl    {recalcule Skip }
  177.   mov ax,80                  {forme la différence 80-largeur }
  178.   sub al,cl
  179.   mov byte ptr skip,al       {et la reporte dans skip }
  180.  
  181.   mov al,byte ptr cpp[di] {charge la largeur de clipping spécifique au plan }
  182.   cmp clip_lt,0           {si pas de clipping à gauche, voyons à droite }
  183.   je @adroite
  184. {sauve en clip_act_lt clip. plan + spécif.}
  185.   mov clipact_lt,ax
  186.   sub Largeur,ax          {réduit le nombre d'octets à copier }
  187.   jmp @clip_rdy           {à droite pas de clipping}
  188. @adroite:                 {si pas de clipping à gauche }
  189.   mov clipact_rt,ax       {clipping pour tous les plans en clip_act}
  190. @clip_rdy:
  191.   mov ax,Largeur          {calcule la largeur totale en octets }
  192.   add ax,clipact_rt
  193.   add ax,clipact_lt
  194.   mul clip_up      {multiplie par le nombre de lignes du clipping supérieur }
  195.   add si,ax        {octets non représentés }
  196.   mov cx,Largeur   {charge la largeur en cx }
  197.   or cl,cl         {largeur 0, plan terminé }
  198.   je @planfini
  199.  
  200.   mov di,ofs            {offset de destination dans l'écran en di}
  201.   mov ah,masqueplan     {réduit le masque de plan aux bits [0..3] }
  202.   and ah,0fh
  203.   mov al,02h            {active le registre 2 du TS (Write Plane Mask)}
  204.   mov dx,3c4h
  205.   out dx,ax
  206.   mov bx,dty                 {initialise le compteur de lignes y }
  207. @lcopy_y:                    {boucle des lignes y }
  208.   add si,clipact_lt          {pointeur source au-delà clipping gauche }
  209.   add di,clipact_lt          {idem pour le pointeur de destination }
  210. @lcopy:                      {boucle des pixels }
  211.   lodsb                      {lit un octet }
  212.   or al,al                   {si 0, pas de traitement }
  213.   je @Valeur0
  214.   stosb                      {sinon copie }
  215. @entry:
  216.   loop @lcopy                {suite de la boucle }
  217.  
  218.   add si,clipact_rt          {après ligne complète, clipping droit }
  219.  
  220.   dec bx                     {incrémente le compteur de lignes }
  221.   je @planfini               {compteur de lignes  = 0, plan suivant }
  222.   add di,skip                {sinon passe en début de ligne suivante }
  223.   mov cx,Largeur             {réinitialise le compteur de colonnes }
  224.   jmp @lcopy_y               {retourne dans la boucle des lignes }
  225. @valeur0:                    {couleur du sprite 0 }
  226.   inc di                     {saute l'octet de destination }
  227.   jmp @entry                 {retourne dans la boucle }
  228. @planfini:                   {fin de la boucle des lignes }
  229.   mov ax,Largeur             {calcul la largeur globale en octets }
  230.   add ax,clipact_rt
  231.   add ax,clipact_lt
  232.   mul clip_dn            {multiplie par le nombre de lignes du clipping inf. }
  233.   add si,ax              {octets non réprésentés }
  234.   rol masqueplan,1       {masque le plan suivant }
  235.   mov cl,masqueplan      {a-t-on sélectionné le plan 0 ?}
  236.   and cx,1               {(bit 1 à 1), alors}
  237.   add ofs,cx             {incrémente de 1 l'offset de destination (cx bit 1 !)}
  238.   inc plane              {incrémente le numéro de plan (indice dans ppp) }
  239.   and plane,3            {réduit de 0 à 3 }
  240.   dec plane_count        {déjà 4 plans copiés, on arrête }
  241.   jne @lplane
  242.   pop ds                 {restaure ds, ciao}
  243. End;                     {asm}
  244. End;
  245.  
  246. Begin
  247. End.
  248.