LE SCROLLING VERTICAL AVEC INSERTION
D'UN DECOR


MECANISME FONCTIONNEL
LA FONCTION
COMMENT UTILISER LA FONCTION
LE FICHIER EXECUTABLE EXEMPLE AVEC SOURCE


MECANISME FONCTIONNEL

Cette fonction est assez complexe pour les néophyte mais largement compréhensible par des initiés. En voici le fonctionnement

 

Cette fonction fait 3 choses distinctes:

Scrolling de l'écran de décor (ecran0)
Transfert de l'écran décor (
ecran0) dans l'écran de travail ou écran final (ecran1)
Initialisation ou non et mise en place de la première ligne des 10 blocks de 32x32 (
scroll_repeat)

Pour ce faire, elle utilise 4 zones mémoires:

Écran de décor (ecran0) en offset 0
Écran final (
ecran1) en offset 64000
La carte des blocks décor (
decor) en offset 480000
Les images PCX des décor (
ecran2/ecran3) en offset 128000
Le flag de fin de niveau (
fin_level) en offset 602000
La valeur (scroll_repeat) en offset 600000.

Pour initialisé le tout, il faut:

Charger les blocks décor par load_map_decor(unsigned char *def_decor)
Initialiser la carte décor par
init_decor(&buffer[0]); (Buffer de totalwar)

 


LA FONCTION

unsigned char scrolling_fond(unsigned char *buf)
{

asm volatile("
pushw %%ds
pushw %%es
pushw %%fs
pushw %%ds
pushw %%ds
popw %%es
popw %%fs
scrolling_fond:
movl %2,%%ebx
addl $
64000,%%ebx /*ecran1 final travail*/
movl %2,%%esi
movl %%esi,%%edi //ecran0
addl $199*320+316,%%edi
addl $198*320+316,%%esi
addl $199*320+316,%%ebx
movl $199*80,%%ecx
std
scrolling_fond1:
lodsl
stosl /*ecran scroll*/
movl %%eax,(%%ebx) /*ecran travail*/
subl $4,%%ebx
decl %%ecx
jne scrolling_fond1

movl %2,%%esi //tabledecor
addl $
480000,%%esi
movl %%esi,%%edi
movw (%%edi),%%ax
orw %%ax,%%ax
jne insert_decor01

xorl %%eax,%%eax
movw 02(%%edi),%%ax
addl %%eax,%%edi
xorl %%eax,%%eax
movb (%%edi),%%al
cmpb $255,%%al
jne reset_insert_decor
xorl %%edx,%%edx
movw 02(%%esi),%%dx
subw $20,%%edx /*bouclage 20 derniers block*/
movw %%dx,02(%%esi)
movl %2,%%edi
movb $1,600002(%%edi) /*flag fin decor*/
addl $
480000,%%edi /*carte decor*/
addl %%edx,%%edi
reset_insert_decor:
movw $32,%%ax
movw %%ax,(%%esi)
pushl %%esi
movw $10,%%ecx
addl $4,%%esi
boucle_calcul_decor:
xorl %%eax,%%eax
movb (%%edi),%%al /*nu de bloc*/
movw %%ax,%%bx

/* modifier le 03/06/98 pour acces 2*64Ko*/

andl $15,%%eax /*partie basse*/
shll $5,%%eax
movl %%eax,(%%esi)
andl $0xf0h,%%ebx
shll $1,%%ebx
movl %%ebx,%%eax
shll $8,%%eax
shll $6,%%ebx
addl %%ebx,%%eax
addl $320*31,%%eax
addl %%eax,(%%esi)
addl $4,%%esi
incl %%edi
decl %%ecx
jne boucle_calcul_decor

popl %%esi
movw $10,%%ax
addw %%ax,02(%%esi)
movl %2,%%ebx
cmpb $0,600000(%%ebx) /*compteur ligne (32)*/
je insert_decor01
subw %%ax,02(%%esi)
decb 600000(%%ebx) /*scroll repeat*/

insert_decor01:
movl %2,%%esi
movl %%esi,%%edi
addl $
480000,%%esi //tabledecor
movl $10,%%ecx
movw $1,%%ax /* optimise ??*/
subw %%ax,(%%esi)
addl $4,%%esi
boucle_affichage_decor:
movl (%%esi),%%eax /*charge adresse block 32 bits*/
pushl %%esi
pushl %%edi
movl %2,%%esi
addl $128000,%%esi /*ecran2*/
addl %%eax,%%esi
pushl %%ecx
movl $8,%%ecx
cld
rep; movsl
popl %%ecx
popl %%edi
popl %%esi
movl $320,%%eax
subl %%eax,(%%esi)
addl $4,%%esi /*sauter 4 octets*/
addl $32,%%edi
decl %%ecx
jne boucle_affichage_decor
insert_decor_fin:
movl %2,%%esi
movl %%esi,%%edi //ecran0
addl $
64000,%%edi //ecran1
movl $80,%%ecx
cld
rep; movsl
jmp fin_du_scrolling
insert_decor_sans_scroll:
movl %2,%%esi
movl %%esi,%%edi //ecran0
addl $
64000,%%edi //ecran1
movl $16000,%%ecx
cld
rep; movsl
fin_du_scrolling:
movl %2,%%edi
fin_routine_scroll_fond:
popw %%fs
popw %%es
popw %%ds
"
:
: "m" (scroll_repeat),"m" (fin_decor), "m" (buf));
return *(buf+fin_decor);
}


COMMENT UTILISER LA FONCTION

1 Créer un tableau avec une carte de décor:

unsigned char map_decor[]={00,00,00,00,00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,
00,00,00,00,00,00,00,00,00,00,


// Placer ici les lignes contenant 10 blocks pour une ligne écran
// comme par exemple
// 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x50,

0x0ff,0x0cc};

Définissez la carte du décor (map decor) de cette façon. Vous devez placer exactement le nombre de 00 comme le montre l'exemple ci-dessus.
La fin du tableau est indiquée par un 0x0ff suivit d'un 0x0cc.

Charger et initialiser le carte décor:

load_map_decor(&map_decor[0]);
init_decor(&buffer[0]);

Ces deux fonctions vont copier les octets contenus dans votre tableau à l'offset 480000 (decor). Ensuite la deuxième fonction va initialiser le pointeur de décor sur le premier block (44), mettre à 0 le compteur scroll_repeat (32 correspondant à la hauteur d'un block).

Faire scroller l'écran avec l'insertion:

unsigned char scrolling_fond(&buffer[0]);
vstoscreen(video,&buffer[ecran1]);

C'est tout. La fonction fait scroller et insert une ligne dans ecran0 puis le transfère dans ecran1.
Vstoscreen permet de visualiser
ecran0 ou écran de travail

Les événements de la routine:

La valeur de retour (unsigned char) indique si différent de 0 si nous sommes arrivés à la fin du décor. A ce point la fonction continue l'insertion sur les 20 derniers blocks. Ce nombre est paramétrable et est indiqué en rouge dans la routine ci-dessus. Les valeurs doivent être des multiples de 10 (équivalent à une ligne de décor). Mettez 20 si vous voulez que la fonction boucle sur les 2 dernières lignes blocks ....


LE FICHIER EXECUTABLE EXEMPLE AVEC SOURCE

Téléchargeable en cliquant ICI.