CODINGSDCC TUT'S PAR STEPHBB75 ★ Put pixel très rapide ★

Sdcc - 12 - Put Pixel Tres RapideCoding Sdcc Tut's Par Stephbb75

Afficher un point très rapidement

On a vue comment afficher un pixel à l'écran avec les fonctions PutPixelMode0, PutPixelMode1 et PutPixelMode2, elles sont déjà rapide, mais on peut encore faire beaucoup plus rapide...
Mais pour cela vous vous en doutez bien, il vas falloir passer pas de l'assembleur.
Je vous propose donc ici 3 fonctions (une pour chaque mode du CPC) pour afficher un pixel de façon ultrarapide, j'ai récupéré les code ASM sur le site The CPC Wiki dans la partie programmation ici

Ce code (les 3 fonctions sont presque identique, juste un changement pour le mode) permet de calculer l'adresse du point et de modifier en mémoire la valeur voulue, elle fait donc la même choses que les fonctions PutPixelModeX, mais en bien plus vite du fait qu'elle ont été faite en ASM.
Petite particularité pour la couleur, en fait le code d'origine utilise une valeur mémoire système qui mémoire la couleur (en fait le GRAPHICS PEN) utilisé, on peut passer par cela ou utiliser une variable globale pour cette couleur, ce que j'ai fait.
Je vous fournie donc aussi la fonction pour initialiser la couleur (attention, elle permet de choisir le No de couleur utiliser, mais de définie pas la couleur)
Aller place au code, j'ai juste francisé les commentaire du code.

Pour le mode 1 :

unsigned char glob_color = 0;

void SetPenM1( unsigned char color )
{
switch ( color % 4 )
{
case 0:
glob_color = 0;
break;
case 1:
glob_color = 240; // 0xF0
break;
case 2:
glob_color = 15; // 0x0F
break;
case 3:
glob_color = 255; // 0xFF
break;
}
}

void PutPixelFastMode1(unsigned int nX, unsigned char nY)
{
// Input: DE = X (0..319), HL = Y (0..199)

__asm

; on récupère les paramètres
LD E, 4(IX)
LD D, 5(IX)

LD L, 6(IX)
LD H,0 ; juste pour être sur.

FPLOT:
LD A, L ;A = octet bas de Y
AND #0x7 ;isole les Bit 0..2 (00000111)
LD H, A ;= y MOD 8 vers H
XOR L ;A = Bit 3..7 of Y
LD L, A ;= (Y\8)*8 vers L
LD C, A ;stock dans C
LD B, #0x60 ;B = &C0\2 = octet haut adresse de deépart de l écran \ 2
; REMARQUE
; si vous voulez dessiner dans un autre écran que celui d'origine en C000 (par exemple 4000)
; il faut changer cette valeur.

ADD HL, HL ;HL * 2
ADD HL, HL ;HL * 4
ADD HL, BC ;+ BC = adresse de deépart
ADD HL, HL ;de la ligne de pixels

LD A, E ;octet bas de X dans A
SRL D ;calcule X\4, Car
RR E ;4 pixels par bit
SRL E
ADD HL, DE ;+ HL = adresse du pixel à modifier

LD C, #0x88 ;masque de bits pour le mode 1 (10001000)
AND #3 ;A = X MOD 4 (00000011)
JR Z, NSHIFT ;-> = 0, aucun deplacement
SHIFT:
SRL C ;déplacer masque de pixel
DEC A ;compteur de boucle
JR NZ,SHIFT ;-position

NSHIFT:
LD A,(#_glob_color); recupere le masque de couleur
; REMARQUE
; La couleur peut etre recupere en memoire a l'adresse B6A3 pour les 664 et 6128 et B338 pour le 464
; moi j'ai préféré passer par un variable globale.
XOR (HL) XOR octet du pixel
AND C AND masque de pixel
XOR (HL) XOR octet du pixel
LD (HL), A ;nouveau octet du pixel

__endasm;
}


la même choses pour le mode 2 :

unsigned char glob_color = 0;

void SetPenM2( unsigned char color )
{
switch ( color % 2 )
{
case 0:
glob_color = 0;
break;
case 1:
glob_color = 255; // 0xF0
break;
}
}

void PutPixelFastMode2(unsigned int nX, unsigned char nY)
{
// Input: DE = X (0..319), HL = Y (0..199)

__asm

; on récupére les paramètres
LD E, 4(IX)
LD D, 5(IX)

LD L, 6(IX)
LD H,0 ; juste pour être sur.

FPLOT:
LD A, L ;A = octet bas de Y
AND #0x7 ;isole les Bit 0..2 (00000111)
LD H, A ;= y MOD 8 vers H
XOR L ;A = Bit 3..7 of Y
LD L, A ;= (Y\8)*8 vers L
LD C, A ;stock dans C
LD B, #0x60 ;B = &C0\2 = octet haut adresse de deépart de l écran \ 2
; REMARQUE
; si vous voulez dessiner dans un autre écran que celui d'origine en C000 (par exemple 4000)
; il faut changer cette valeur.

ADD HL, HL ;HL * 2
ADD HL, HL ;HL * 4
ADD HL, BC ;+ BC = adresse de deépart
ADD HL, HL ;de la ligne de pixels

SRL D ;calcule X\8, Car
RR E ;8 pixels par bit
SRL D
RR E
SRL E
ADD HL, DE ;+ HL = adresse du pixel à modifier

LD C, #0x80 ;masque de bits pour le mode 2 (10000000)
AND #7 ;A = X MOD 8 (00000111)
JR Z, NSHIFT ;-> = 0, aucun deplacement
SHIFT:
SRL C ;déplacer masque de pixel
DEC A ;compteur de boucle
JR NZ,SHIFT ;-position

NSHIFT:
LD A,(#_glob_color); recupere le masque de couleur
; REMARQUE
; La couleur peut etre recupere en memoire a l'adresse B6A3 pour les 664 et 6128 et B338 pour le 464
; moi j'ai préféré passer par un variable globale.
XOR (HL) XOR octet du pixel
AND C AND masque de pixel
XOR (HL) XOR octet du pixel
LD (HL), A ;nouveau octet du pixel

__endasm;
}


Et pour finir, la même pour le mode 0

unsigned char glob_color = 0;

void SetPenM0( unsigned char color )
{
switch ( color % 16 )
{
case 0:
glob_color = 0;
break;
case 1:
glob_color = 192; // 0xC0
break;
case 2:
glob_color = 12; // 0x0C
break;
case 3:
glob_color = 204; // 0xCC
break;
case 4:
glob_color = 48; // 0x30
break;
case 5:
glob_color = 240; // 0xF0
break;
case 6:
glob_color = 60; // 0x3C
break;
case 7:
glob_color = 252; // 0xFC
break;
case 8:
glob_color = 3; // 0x03
break;
case 9:
glob_color = 195; // 0xc3
break;
case 10:
glob_color = 15; // 0x0F
break;
case 11:
glob_color = 207; // 0xCF
break;
case 12:
glob_color = 51; // 0x33
break;
case 13:
glob_color = 243; // 0xF3
break;
case 14:
glob_color = 63; // 0x3F
break;
case 15:
glob_color = 255; // 0xFF
break;
}
}

void PutPixelFastMode0(unsigned int nX, unsigned char nY)
{
// DE = X (0..159), HL = Y (0..199)

__asm

; on récupére les paramètres
LD E, 4(IX)
LD D, 5(IX)

LD L, 6(IX)
LD H,0 ; juste pour être sur.

FPLOT:
LD A, L ;A = octet bas de Y
AND #0x7 ;isole les Bit 0..2 (00000111)
LD H, A ;= y MOD 8 vers H
XOR L ;A = Bit 3..7 of Y
LD L, A ;= (Y\8)*8 vers L
LD C, A ;stock dans C
LD B, #0x60 ;B = &C0\2 = octet haut adresse de deépart de l écran \ 2
; REMARQUE
; si vous voulez dessiner dans un autre écran que celui d'origine en C000 (par exemple 4000)
; il faut changer cette valeur.

ADD HL, HL ;HL * 2
ADD HL, HL ;HL * 4
ADD HL, BC ;+ BC = adresse de deépart
ADD HL, HL ;de la ligne de pixels


SRL E ;calcule X\2, Car 2 pixels par bit

LD C, #0xAA ;masque de bits pour le mode 0 (10101010)
JR Z, NSHIFT ;-> = 0, aucun deplacement
SHIFT:
LD C,#0x55 ;masque pour les autres pixel de droite (01010101)

SRL C ;déplacer masque de pixel
DEC A ;compteur de boucle
JR NZ,SHIFT ;-position

NSHIFT:
ADD HL, DE ;+ HL = adresse du pixel à modifier
LD A,(#_glob_color); recupere le masque de couleur
; REMARQUE
; La couleur peut etre recupere en memoire a l'adresse B6A3 pour les 664 et 6128 et B338 pour le 464
; moi j'ai préféré passer par un variable globale.
XOR (HL) XOR octet du pixel
AND C AND masque de pixel
XOR (HL) XOR octet du pixel
LD (HL), A ;nouveau octet du pixel

__endasm;
}

Pour faire une comparaison, j'ai repris le code fait pour la fonction PutPixelMode1, il suffit de mettre la nouvelle fonction. Tout est dans le ZIP, voici le résultat ....

Les animations sont fidèles en temps vis à vis d'un CPC
A Gauche avec la fonction PutPixelFastMode1 et à droite avec la fonction PutPixelMode1

stephbb75

ANNÉE: 2013
★ AUTEUR: Stephbb75

Page précédente : Sdcc - 11 - Attaquer le Crtc

★ AMSTRAD CPC ★ A voir aussi sur CPCrulez , les sujets suivants pourront vous intéresser...

Lien(s):
» Coding » Sdcc - 05 - Ecrire du Text
» Coding » Sdcc - 09 - Cls Ultra Rapide
» Coding » Sdcc - 07 - Ecrire un Fichier sur une Disquette
» Coding » Developper en C pour CPC (Stephbb75)
» Coding » Sdcc - 03 - Fichier Bat Pour Compiler Avec Sdcc
» Coding » Sdcc - 15 - Animation Par Sprite
Je participe au site:

» Vous avez remarqué une erreur dans ce texte ?
» Aidez-nous à améliorer cette page : en nous contactant via le forum ou par email.

CPCrulez[Content Management System] v8.7-desktop/c
Page créée en 311 millisecondes et consultée 2266 fois

L'Amstrad CPC est une machine 8 bits à base d'un Z80 à 4MHz. Le premier de la gamme fut le CPC 464 en 1984, équipé d'un lecteur de cassettes intégré il se plaçait en concurrent  du Commodore C64 beaucoup plus compliqué à utiliser et plus cher. Ce fut un réel succès et sorti cette même années le CPC 664 équipé d'un lecteur de disquettes trois pouces intégré. Sa vie fut de courte durée puisqu'en 1985 il fut remplacé par le CPC 6128 qui était plus compact, plus soigné et surtout qui avait 128Ko de RAM au lieu de 64Ko.