Obligement - L'Amiga au maximum

Vendredi 29 mars 2024 - 16:02  

Translate

En De Nl Nl
Es Pt It Nl


Rubriques

Actualité (récente)
Actualité (archive)
Comparatifs
Dossiers
Entrevues
Matériel (tests)
Matériel (bidouilles)
Points de vue
En pratique
Programmation
Reportages
Quizz
Tests de jeux
Tests de logiciels
Tests de compilations
Trucs et astuces
Articles divers

Articles in english


Réseaux sociaux

Suivez-nous sur X




Liste des jeux Amiga

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z,
ALL


Trucs et astuces

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z


Glossaire

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z


Galeries

Menu des galeries

BD d'Amiga Spécial
Caricatures Dudai
Caricatures Jet d'ail
Diagrammes de Jay Miner
Images insolites
Fin de jeux (de A à E)
Fin de Jeux (de F à O)
Fin de jeux (de P à Z)
Galerie de Mike Dafunk
Logos d'Obligement
Pubs pour matériels
Systèmes d'exploitation
Trombinoscope Alchimie 7
Vidéos


Téléchargement

Documents
Jeux
Logiciels
Magazines
Divers


Liens

Associations
Jeux
Logiciels
Matériel
Magazines et médias
Pages personnelles
Réparateurs
Revendeurs
Scène démo
Sites de téléchargement
Divers


Partenaires

Annuaire Amiga

Amedia Computer

Relec


A Propos

A propos d'Obligement

A Propos


Contact

David Brunet

Courriel

 


Programmation : C - Ouverture d'un écran avec graphics.library
(Article écrit par Pascal Amiable et extrait d'Amiga News Tech - mars 1991)


En tant qu'ordinateur multitâche, l'Amiga possède une gestion d'écran assez particulière, mais ô combien efficace. Qui n'a jamais été amusé ou surpris, la première fois, de faire défiler l'écran du Workbench du bout de sa souris.

Cette série d'articles a pour but de vous faire mieux connaître deux des bibliothèques de l'Amiga, à savoir Graphics et Intuition.

La graphics.library contient toutes les fonctions de gestion des objets graphiques de base (écrans, sprites, BOB) ainsi que les primitives de dessin (points, droites, cercles, remplissage...). L'intuition.library, quant à elle, est une plate-forme permettant le développement d'interfaces conviviales à base de menus, gadgets variés et autres fenêtres.

Cette étude sera formée d'une partie théorique et d'une série d'exemples, pour la plupart en langage C. Une connaissance du C (ou de tout autre langage structuré) sera donc très utile, ainsi parfois que des rudiments d'assembleur. Enfin, un certain nombre de termes anglo-saxons difficilement traduisibles en français seront utilisés tout au long de cet article. En cas d'incompréhension, reportez-vous au lexique de fin.

Les concepts de base

Lorsque l'on crée une zone de visualisation, il faut prendre en compte deux éléments essentiels, qui sont le "playfield" (champ de jeu) et les "sprites". Le champ de jeu représente la partie statique de la zone de visualisation, alors que les sprites peuvent se déplacer et interférer entre eux ou avec le champ de jeu. Nous étudierons les sprites en détails dans un prochain article.

Pour projeter son affichage, l'Amiga utilise une technique de balayage vidéo connue sous le nom de "Raster Display". Cette image est formée d'un certain nombre de lignes horizontales, créées par le faisceau électronique du moniteur. En mode normal, c'est-à-dire non entrelacé, il est possible d'afficher 256 lignes horizontales (200 en mode NTSC). En mode entrelacé, on peut afficher 512 lignes (400 en NTSC). Comment est-ce possible ? C'est assez simple : pour afficher 512 lignes, l'Amiga commence par afficher en 1/60e de seconde une première série de 256 lignes représentant les lignes paires de l'image à afficher, puis il affiche les 256 lignes impaires après avoir décalé la position verticale de départ d'une demie épaisseur de ligne. Il existe toutefois un inconvénient à ce mode : pour tracer une image en mode entrelacé, l'Amiga met deux fois plus de temps, soit 1/30e de seconde. Or ce délai est trop long pour obtenir un affichage de qualité visuelle standard, ce qui explique le scintillement, si disgracieux, du mode entrelacé.

Chaque ligne visualisée est composée d'un certain nombre de points. Deux modes de précision horizontale sont également proposés. En basse résolution, chaque ligne compte 320 points, alors qu'en haute résolution, il est possible d'avoir 640 points par ligne. L'affichage en haute résolution ne permet plus que d'obtenir 16 couleurs à l'écran alors que nous en avions 32 en basse résolution. A noter la présence des modes EHB et HAM qui permettent respectivement d'obtenir 64 et 4096 couleurs simultanément à l'écran avec toutefois quelques contraintes, mais nous y reviendrons plus tard.

Pour dessiner à l'écran, il est nécessaire d'écrire dans une portion de mémoire, portion qui représente la zone de visualisation qui va être affichée sur le moniteur. Cette zone de mémoire est organisée sous forme de plans de bits. Un plan de bits représente une zone virtuelle de traçage, permettant d'afficher une seule couleur (mise à zéro ou à un de chaque bit de la zone). L'affichage avec plusieurs couleurs est possible en superposant plusieurs plans de bits. On obtient alors 2^N couleurs, où N représente le nombre de plans de bits. Cette gestion des couleurs par superposition de plans de bits est réalisée grâce à un circuit spécialisé portant le doux nom de Denise. Un maximum de 6 plans de bits superposés est autorisé, soit dans l'absolu 2^6 couleurs (64). Cet assemblage de plans de bits s'appelle une bitmap (Cf Fig 1).

C

Structures et fonctions d'affichage

L'Amiga produit une zone d'affichage à partir d'une série d'instructions organisée sous la forme d'une structure C et baptisée "View". Cette zone d'affichage peut être décomposée en plusieurs parties distinctes, séparées par au minimum une ligne horizontale (une ligne de "raster") : ce sont les "ViewPorts", qui forment donc des zones rectangulaires (Cf. Fig 2). Le ViewPort correspond au CustomScreen d'Intuition, que nous étudierons plus tard.

C

Pour définir un ViewPort, il faut dans un premier temps initialiser quelques paramètres : sa taille (hauteur et largeur), sa profondeur (le nombre de plans de bits utilisés) qui indique le nombre de couleurs, son mode de visualisation (basse ou haute résolution, entrelacement...), l'adresse de la zone de mémoire utilisée pour l'affichage, et enfin sa position par rapport au coin haut et gauche de l'écran.

La hauteur est associée au champ DHeight de la structure ViewPort. Elle représente le nombre de lignes verticales du ViewPort. La largeur, elle, est contenue dans le champ DWidth. Elle représente le nombre de pixels (points) par lignes du ViewPort. Il est possible de définir pour chaque ViewPort des largeurs différentes.

Le nombre de plans de bits utilisés pour la mémoire d'affichage, conditionne le nombre de couleurs affichables dans le ViewPort sous la forme déjà citée nombre_couleurs = 2^nombre_plans_de_bits. A noter le cas particulier du mode HAM qui autorise avec une profondeur de 6 plans de bits, l'affichage de 4096 couleurs, avec toutefois des contraintes de proximité. La profondeur est codée dans le champ utilisé Depth.

A chaque ViewPort est associée une palette de couleurs. Cette palette est spécifiée dans une structure baptisée ColorMap et rattachée au ViewPort par son adresse. Nous verrons cela un peu plus loin.

Il existe neuf modes possibles de visualisation, le mode par défaut étant la basse résolution. Pour choisir un autre mode, il faut remplir le champ Modes avec les valeurs adéquates, suivant la liste ci-dessous :
  • Basse résolution (Null) : dans ce mode, une ligne normale overscan (alias suraffichage).
  • Haute résolution (Hires) : la résolution horizontale passe ici à 640 pixels, ou 704 en suraffichage.
  • Entrelacé (Lace) : l'affichage s'effectue en mode entrelacé, soit 512 lignes par écran au lieu de 256. Attention ! Lorsque vous spécifiez le mode Lace dans le ViewPort, vous devez impérativement le spécifier également dans le champ View.Modes.
  • Hold & Modify (HAM) : mode spécial permettant l'affichage de 4096 couleurs simultanées à l'écran.
  • Double playfield (DualPF) : le ViewPort est traité comme possédant deux zones d'affichage superposées et indépendantes.
  • Avec Sprites (Sprites) : cette valeur est obligatoire pour indiquer à l'Amiga que l'on va utiliser des sprites matériels.
  • Playfield 2 avant 1 (PFBA) : cette valeur est liée au mode DualPF et permet de positionner le champ de jeu 2 devant le premier.
  • ViewPort caché (VP Hide) : indique que le ViewPort est caché et par là même, que son contenu n'est pas visualisé à l'écran.
  • Mode 64 couleurs (Extra_HalfBrite) : dans ce mode, 64 couleurs sont affichées, les 32 dernières étant dérivées des 32 premières.
Pour obtenir, par exemple, un écran en haute résolution entrelacée, on mettra Hires+Lace dans le champ Modes.

Comme le ViewPort est de taille égale ou inférieure à la zone de visualisation, il est nécessaire d'indiquer sa position à l'écran. Cette position est définie par les distances DxOffset et DyOffset entre le coin supérieur gauche de l'écran et le coin supérieur gauche du ViewPort (Cf. Fig 3). DxOffset doit être compris entre -16 et +352 (-32 et +704 en Hires), DyOffset entre -16 et +256 (-32 et +512 en mode Lace) sachant que (0,0) positionne le ViewPort strictement dans le coin haut et gauche de l'écran. DxOffset et DyOffset sont deux champs de la structure ViewPort.

C

La zone de mémoire réservée pour l'affichage peut être plus grande que l'écran de visualisation, et ce, jusqu'à la taille limite de 1024x1024 points. C'est justement pour cela qu'il faut spécifier la position du ViewPort dans cette zone d'affichage, suivant le même principe que ci-dessus et à l'aide des champs RxOffset et RyOffset (Cf. Fig 4). Ces deux valeurs sont stockées dans les champs de la structure RasInfo portant le même nom. Cette structure contient également un pointeur sur la Bitmap d'affichage (structure BitMap).

C

Nous en savons maintenant assez pour créer notre propre écran. L'exemple ci-joint va nous permettre de passer en douceur de la théorie à la pratique, en créant un simple ViewPort d'une taille de 320x200 avec une bitmap de même taille. Il démontre également la manière de placer ce ViewPort par rapport à la structure View.

/*
	Programmation : C - Ouverture d'un écran avec graphics.library
	Article écrit par Pascal Amiable et extrait d'Amiga News Tech - mars 1991
	http://obligement.free.fr/articles/c_ecrans_graphics.php

	Adapté à vbcc par Tygre, 2020/09/06
*/

/* ----------------------------------------------------------------- */
/*     Ouverture d'un écran sous graphics...                         */
/*     Auteur Pascal AMIABLE (c) 1991                                */
/* ----------------------------------------------------------------- */

#include <exec/exec.h>
#include <exec/types.h>
#include <graphics/gfx.h>
#include <graphics/rastport.h>
#include <graphics/copper.h>
#include <graphics/view.h>
#include <graphics/gels.h>
#include <graphics/regions.h>
#include <graphics/clip.h>
#include <graphics/text.h>
#include <graphics/gfxbase.h>
#include <hardware/dmabits.h>
#include <hardware/custom.h>
#include <hardware/blit.h>

#define PLAN     2          /* Nombre de Bitplane associé à l'écran */
#define COLOR    4          /* Nombre de couleurs disponibles */
#define HORIZONT 640        /* Largeur de l'écran en pixels */
#define VERT     512        /* Hauteur de l'écran en pixels */
#define MODE_V   LACE       /* Mode de visualisation du View (entrelacé) */
#define MODE_VP  HIRES+LACE /* Mode de visualisation ViewPort */
							/* Haute résolution et entrelacé  */

int i;

struct View view;         /* View associé à l'écran */
struct ViewPort viewport; /* ViewPort associé à View */
struct RasInfo rasinfo;   /* Structure RasInfo liée au ViewPort */
struct BitMap bitmap;     /* BitMap lié au ViewPort */
struct RastPort rastport; /* Le RastPort avec lequel on dessine */

struct GfxBase *GfxBase; /* Pointeur sur la graphics.library */

struct View *ecran_sauvegarde; /* Pointeur sur une structure View afin de sauvegarder l'écran courant */

UWORD colortable[COLOR] = { 0x000, 0xf00, 0x0f0, 0x00f };
 /* Table des couleurs, couleur 0 = NOIR, couleur 1 = ROUGE, couleur 2 = VERT, couleur 3 = BLEU */

char *bouton_gauche = (char *)0xbfe001;
 /* Port A du CIA dont le bit correspond au bouton gauche de la souris */

void init(), ouvreecran(), libere();

/* ----------------------------------------------------------------- */
/*     Programme principal                                           */
/* ----------------------------------------------------------------- */

int main()
{
	init();
	ouvreecran();
	Move(&rastport, 100, 100);
	Draw(&rastport, 200, 200);
	while(!((*bouton_gauche & 0x40) - 64)); /* Tant que le bouton gauche de la souris n'est pas enfoncé */
	LoadView(ecran_sauvegarde);             /* Restauration du View sauvegardé */
	libere();
}

/* ----------------------------------------------------------------- */
/*     init() Ouvre la bibliothèque et sauvegarde l'ancien écran     */
/* ----------------------------------------------------------------- */

void init()
{
	if ((GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 0)) == NULL)
		exit(1); /* La bibliothèque graphics ne veut pas s'ouvrir */

	ecran_sauvegarde = GfxBase->ActiView; /* Sauvegarde du View actif */
}

/* ----------------------------------------------------------------- */
/*     ouvreecran() Initialise et ouvre un écran                    */
/* ----------------------------------------------------------------- */

void ouvreecran()
{
	InitView(&view);      /* Initialisation de la structure View */
	InitVPort(&viewport); /* Initialisation de la structure ViewPort */

	view.ViewPort = &viewport; /* On lie le ViewPort au View */
	view.Modes = MODE_V;       /* On indique le mode visualisation du View */
	
	InitBitMap(&bitmap, PLAN, HORIZONT, VERT); /* On initialise la bitmap */
	
	rasinfo.BitMap = &bitmap; /* Liaison de la BitMap avec le RasInfo */
	rasinfo.RxOffset = 0;
	rasinfo.RyOffset = 0;
	rasinfo.Next = NULL;      /* Pas d'autres structures */
	
	viewport.DxOffset = 0; /* On remplit la structure ViewPort */
	viewport.DyOffset = 0; /* cf. l'article ci-dessus */
	viewport.DWidth = HORIZONT;
	viewport.DHeight = VERT;
	viewport.RasInfo = &rasinfo;
	viewport.Modes = MODE_VP;
	viewport.Next = NULL;  /* Pas d'autre ViewPort */

	viewport.ColorMap = (struct ColorMap *)GetColorMap(COLOR);
                        /* Initialisation de la ColorMap du ViewPort */
	LoadRGB4(&viewport, colortable, COLOR);
                       /* Chargement des couleurs dans la ColorMap */

	for(i = 0; i < PLAN; i++) /* Allocation des bitplanes */
	{
		if((bitmap.Planes[i] = (PLANEPTR)AllocRaster(HORIZONT, VERT)) == NULL)
			exit(2);
		BltClear((UBYTE *)bitmap.Planes[i], RASSIZE(HORIZONT, VERT), 0);
                                   /* Éffacement de bitplanes au Blitter */
	}
	
	InitRastPort(&rastport);    /* Initialisation du RastPort */
	rastport.BitMap = &bitmap; /* On lie le RastPort à la bitmap dans laquelle on dessine */
	
	MakeVPort(&view, &viewport); /* On crée la zone de visualisation */
	MrgCop(&view);               /* et la CopperList associée */
	LoadView(&view);             /* et on affiche l'écran sur le moniteur */
}

/* ----------------------------------------------------------------- */
/*     libere() Libère la mémoire utilisée                           */
/* ----------------------------------------------------------------- */

void libere()
{
	for(i = 0; i < PLAN; i++) /* On libère la mémoire des bitplanes */
		FreeRaster(bitmap.Planes[i], HORIZONT, VERT);
	
	FreeColorMap(viewport.ColorMap); /* On libère la mémoire de la ColorMap */
	
	FreeVPortCopLists(&viewport); /* Libération de la CopperList */
	
	CloseLibrary((struct Library *)GfxBase); /* Fermeture de la bibliothèque graphics */
}

Mise à jour de septembre 2020 : une archive contenant le listing adapté à vbcc, et avec les exécutables compilés par SAS C et vbcc, a été réalisée par Yann-Gaël Guéhéneuc et est disponible sur obligement.free.fr/files/antscreenwithgraphicslibrary.lha.

Le mois prochain, nous verrons la génération de champs de jeu avec Intuition, ce qui nous permettra d'étudier les différences entre les deux méthodes.

Petit lexique
  • Bitmap : assemblage de plans de bits, permettant de créer un écran pour le traçage en multi-couleurs.
  • bitsplane : littéralement, plan de bits. Il s'agit d'une zone de mémoire organisée sous forme rectangulaire, permettant de représenter un écran de traçage virtuel.
  • BOB : alors que le sprite est indépendant du champ de jeu, le BOB en fait partie intégrante. Ce qui signifie que l'on doit gérer son interaction avec le champ de jeu. C'est le principe des brosses dans un logiciel de dessin.
  • Copper : processeur spécialisé de l'Amiga. Synchronisé sur le spot vidéo, il a été conçu pour gérer la partie affichage de l'Amiga grâce à son jeu d'instructions propres.
  • Library : en français bibliothèque. Ce terme est utilisé pour désigner les bibliothèques de fonctions du système d'exploitation de l'Amiga, qu'elles soient en ROM ou sur disquette (exemple : graphics.library).
  • Sprite : lutin en français. Il représente un objet graphique indépendant du champ de jeu qui peut se déplacer en superposition de celui-ci sans en modifier le contenu (idéal pour représenter, par exemple, un petit vaisseau se déplaçant sur un fond).


[Retour en haut] / [Retour aux articles] [Article suivant]