Page 1 sur 1

CPC : Adresse écran vers coordonnées X,Y

Posté : 08 août 2017 10:34
par Baptiste
Bonjour,

Je cherche le moyen de convertir une adresse écran, en coordonnées X et Y, pour AMSTRAD CPC. Pour tous les modes d'écran.

Merci pour votre aide.

Re: CPC : Adresse écran vers coordonnées X,Y

Posté : 08 août 2017 12:50
par rendomizer
en 40 colonnes tu fais :
colonnes=40
poke "adress ecran+x+y+colonnes",donnée et tu as la position x et y !

en 80 colonnes tu fais :
colonnes=80
poke "adress ecran+x+y+colonnes",donnée et tu as la position x et y !

en 320 colonnes tu fais :
colonnes=320
poke "adress ecran+x+y+colonnes",donnée et tu as la position x et y !


maintenant je ne sais pas comment sont organisé les bipmaps (en blocks de 8x10 en lignes...)

Re: CPC : Adresse écran vers coordonnées X,Y

Posté : 08 août 2017 13:06
par Baptiste
Merci,

Il y a 80 octets par ligne (quelque soit le mode d'affichage). Là où ça se complique, c'est qu'il y a un saut de 8 pixels verticalement à chaque fois. Par exemple, la plage &C000 à &C04F correspond à la 1ère ligne. Mais &C050 correspond à la 9ème ligne. En fait, la deuxième ligne commence à l'adresse &C800. Et ainsi de suite jusqu'à &FFFF.

Du coup, c'est un peu chaud pour récupérer la position X et Y (en pixel) d'une adresse mémoire.

Re: CPC : Adresse écran vers coordonnées X,Y

Posté : 08 août 2017 14:47
par __sam__
Baptiste a écrit :Du coup, c'est un peu chaud pour récupérer la position X et Y (en pixel) d'une adresse mémoire.
Pas tant que ca. Si tu divises (addr-&C000) par 8*80=640, tu as l'index du bloc de 8 pixels de haut, et le décalage dans ce bloc est le reste modulo 8 de int((addr-&C000)/80). Quant au X ca dépend de la résolution, mais pour faire simple c'est le reste de (addr-&C000)/80 mutliplié par le nb de pixels converts par un octet. Ca nous donne quelque chose comme:

Code : Tout sélectionner

REM en entrée, RESOX est la resolution en X de l'écran (160, 320 ou 640)
REM en entrée, ADDR est l'adresse d'un octet de l'écran. En sortie on a X et Y par les formules suivantes:

    X=((ADDR-&C000) MOD 80)*(RESOX/80)
    Y=8*INT((ADDR-&C000)/640) + (INT((ADDR-&C000)/80) MOD 8)

REM en sortie X=0..RESOX-1 (par pas de RESOX/80) et Y=0..199
(on peut optimiser ca si on veut avec des divisions entières et des bitmasks pour le MOD 8, mais je pense que comme ça c'est plus clair je trouve.)

NOTA:
1) INT(x) c'est la troncature d'un nombre vers l'entier immédiatement en dessous ou lui même si le nombre est déjà entier.
2) x MOD Y c'est le calcul de x modulo y.
3) A partir de l'adresse seule tu ne peux pas obtenir la précision au pixel près en X. Uniquement à l'octet pret, soit 2 pixels en 160x200, 4 pixels en 320x200 et 8 pixels en 640x200, c'est à dire (RESOX/80) pixels couverts par octets.

Re: CPC : Adresse écran vers coordonnées X,Y

Posté : 08 août 2017 15:24
par Baptiste
__sam__ a écrit :(...)
Je teste ça. Merci ;)

Re: CPC : Adresse écran vers coordonnées X,Y

Posté : 08 août 2017 16:14
par Baptiste
J'ai tenté l'algo. J'ai effectué la conversion pour le Javascript :

Code : Tout sélectionner

		var _size = 0;
		if(CPCJS._mode == 0){
			_size = 160;
		}
		
		if(CPCJS._mode == 1){
			_size = 320;
		}

		if(CPCJS._mode == 2){
			_size = 640;
		}

		position.x = ((address-0xC000) % 80)*(_size/80);
		position.y = 8*Math.round((address-0xC000)/640) + (Math.round((address-0xC000)/80) % 8);
Lorsque je demande les coordonnées X et Y de l'adresse &D000, cela me renvoi X=64 et Y=51 (sous Javascript), alors q'un POKE &D000,255 sur Amstrad place le point a X=0 et Y=2.

A votre avis, d'où vient le problème ?

Merci.

Re: CPC : Adresse écran vers coordonnées X,Y

Posté : 08 août 2017 16:21
par __sam__
Le Math.round() est suspect. Cela ne retourne pas l'entier immédiatement inférieur: Math.round(0.6) donne 1. Ca arrondit vers l'entiers le plus proche. Essaye avec math.floor() plutôt. Ensuite _size/80 vaut exactement (2<<CPCJS._mode), donc tu peux retirer les if() du début et remplacer _size/80 par le 2<<_mode. Mais ce n'est pas la cause du bug :)

En fait l'organisation mémoire est différente de celle que je croyais. >>Ici<< on trouve l'organisation mémoire exacte et une formule intéressante:

Code : Tout sélectionner

address = 0xC000 + ((Line / 8) * 80) + ((Line % 8) * 2048)
que l'on peut inverser pour trouver le bon Y:

Code : Tout sélectionner

Y = ((address - 0xC000)%80)*8 + math.floor((address - 0xC000)/2048)
Pour le X, c'est un chouilla plus compliqué aussi: il faut masquer le truc en 2048 pour que la formule "modulo 80" marche

Code : Tout sélectionner

X = (((address - 0xC000) % 2048) % 80) * (_size/80)
Avec ces dernières formules je crois que ca marche nettement mieux :D

Re: CPC : Adresse écran vers coordonnées X,Y

Posté : 08 août 2017 17:41
par Baptiste
__sam__ a écrit :(...)
Lorsque je test &C050, il devrait me retourner X=0 et Y=8, mais il me retourne X=0 et Y=0. Pour &D000, il devrait me retourner X=0 et Y=2, mais il me retourne X=0 et Y=130.

Le X semble bon

Re: CPC : Adresse écran vers coordonnées X,Y

Posté : 08 août 2017 18:25
par __sam__
Arf oui, toujours ce 2048 que j'ai oublié dans le Y. je dois re-regarder..... arf fichue architecture non linéaire

Code : Tout sélectionner

Y = math.floor(((address - 0xC000)%2048)/80)*8 + math.floor((address - 0xC000)/2048)
me semble mieux (on y est presque ;) )

Re: CPC : Adresse écran vers coordonnées X,Y

Posté : 09 août 2017 09:21
par Baptiste
__sam__ a écrit :(quote inutile supprimée...)
Cela fonctionne mieux. Merci beaucoup.