Corso di AmigaOS

Torna all'elenco delle lezioniPer dubbi, consigli o richieste, potete mandare un'e-mail ad Andrea Carolfi.
Ringraziamo Amiga Transactor Mailing List per questo tangibile contributo!


La Graphics.Library (Quindicesima lezione)

In questa lezione cominceremo ad avvicinarci ad un'altra importante libreria del sistema operativo di Amiga: la graphics.library. Questa enorme libreria (conta ben 179 funzioni pubbliche) si incarica di interfacciarsi con l'hardware grafico di Amiga e permette di compiere un certo numero di operazioni grafiche.
Purtroppo, quello che manca a questa libreria è un completo supporto RTG per l'hardware che fortunatamente è possibile aggiungere tramite CGX o Picasso96 sostituendo alcune funzioni di questa libreria per permettergli di operare anche senza il chipset (vedi DraCo).
Comunque, seguendo alcuni accorgimenti è possibile, avvalendosi del display database, far girare la propria applicazione grafica sia su schermo OCS/ECS/AGA che su scheda grafica.

Prima di vedere le primitive grafiche di questa lezione, è necessario specificare che praticamente tutte le funzioni grafiche necessitano di una bitmap associata ad una rastport.
Vediamo dunque queste strutture.

BitMap e RastPort

typedef UBYTE *PLANEPTR;

struct BitMap
{
         UWORD   BytesPerRow;
         UWORD   Rows;
         UBYTE   Flags;
         UBYTE   Depth;
         UWORD   pad;
         PLANEPTR Planes[8];
};

struct RastPort
{
         struct  Layer *Layer;
         struct  BitMap   *BitMap;
         UWORD  *AreaPtrn;        /* ptr to areafill pattern */
         struct  TmpRas *TmpRas;
         struct  AreaInfo *AreaInfo;
         struct  GelsInfo *GelsInfo;
         UBYTE   Mask;       /* write mask for this raster */
         BYTE    FgPen;         /* foreground pen for this raster */
         BYTE    BgPen;         /* background pen  */
         BYTE    AOlPen;        /* areafill outline pen */
         BYTE    DrawMode;         /* drawing mode for fill, lines, and text */
         BYTE    AreaPtSz;         /* 2^n words for areafill pattern */
         BYTE    linpatcnt;        /* current line drawing pattern preshift */
         BYTE    dummy;
         UWORD  Flags;      /* miscellaneous control bits */
         UWORD  LinePtrn;      /* 16 bits for textured lines */
         WORD   cp_x, cp_y;       /* current pen position */
         UBYTE   minterms[8];
         WORD   PenWidth;
         WORD   PenHeight;
         struct  TextFont *Font;   /* current font address */
         UBYTE   AlgoStyle;        /* the algorithmically generated style */
         UBYTE   TxFlags;       /* text specific flags */
         UWORD   TxHeight;         /* text height */
         UWORD   TxWidth;       /* text nominal width */
         UWORD   TxBaseline;       /* text baseline */
         WORD    TxSpacing;        /* text spacing (per character) */
         APTR    *RP_User;
         ULONG   longreserved[2];
#ifndef GFX_RASTPORT_1_2
         UWORD   wordreserved[7];  /* used to be a node */
         UBYTE   reserved[8];      /* for future use */
#endif
};

La bitmap è proprio dove le operazioni grafiche andranno a scrivere o leggere (a seconda della funzione chiamata). La rastport contiene informazioni sullo stato attuale di colore di sfondo, colore di primo piano, posizione del cursore grafico, carattere utilizzato e via di seguito.
Abbiamo una rastport per ogni finestra e una per ogni schermo, ma non è strettamente necessario. E' possibile avere una bitmap e una rastport "nascoste" su cui lavorare internamente per poi ricopiare sulla finestra (double buffering).
Vediamo quindi come creare una bitmap. Una volta, era necessario allocare i vari piani necessari, inzializzarli, allocare la bitmap, inizializzarla, collegare i piani alla bitmap, e poi collegare la bitmap alla rastport. A partire dal 3.0 viene messa a disposizione la funzione AllocBitMap() che facilita l'operazione;
vediamo:

        struct RastPort rp;
        struct BitMap *bm;

        InitRastPort(&rp);

        if((bm = AllocBitMap(320,200,8,BMF_CLEAR,NULL)))
        {
                rp.BitMap = bm;

                ...

                FreeBitMap(bm);
        }

Questo stralcio di codice, inizializza una rastport ai valori predefiniti, alloca una bitmap ad otto piani (256 colori) di dimensioni 320x200 inizializzandola al colore 0 e collegandola alla rastport precedentemente valorizzata.
Successivamente la bitmap viene deallocata.

Il campo NULL della funzione è un puntatore ad una bitmap "amica" (in questo caso nessuna) che può essere richiesta per allocare la bitmap in modo da rendere le blittate dalla bitmap a quella amica più efficenti.

Primitive grafiche

Vediamo adesso alcune primitive grafiche:

void DrawEllipse( struct RastPort *rp, long xCenter, long yCenter, long a, long b );
Disegna sulla RastPort rp, un ellisse di centro (xCenter,yCenter) e raggi a b. Se vogliamo disegnare un cerchio non bisogna far altro che specificare lo stesso valore per entrambi i raggi.

void SetRast( struct RastPort *rp, unsigned long pen );
Ripulisce con il colore pen la RastPort rp cancellando quindi tutto il suo contenuto.

void Move( struct RastPort *rp, long x, long y );
Sposta il cursore grafico alle coordinate x,y.

void Draw( struct RastPort *rp, long x, long y );
Traccia una riga dalla posizione attuale del cursore grafico fino alle coordinate x e y specificate.

void RectFill( struct RastPort *rp, long xMin, long yMin, long xMax, long yMax );
Disegna un rettangolo pieno con angolo superiore sinistro xMin yMin e angolo inferiore destro xMax yMax.

!!! ATTENZIONE !!!

if(xMax < xMin || yMax < yMin) crashsystem();

In parole :-) : le coordinate xMax e yMax devono essere maggiori o uguali a xMin e yMin, altrimenti si pianta tutto il sistema.

ULONG ReadPixel( struct RastPort *rp, long x, long y );
Restituisce il valore del colore usato dal pixel posizionato alle coordinate (x,y) specificate.

LONG WritePixel( struct RastPort *rp, long x, long y );
Cambia il colore del pixel posizionato alle coordinate (x,y), in accordo con quello specificato tramite SetAPen. Ritorna 0 in caso di successo o -1 nel caso in cui il punto sia fuori dalla RastPort.

void SetAPen( struct RastPort *rp, unsigned long pen );
Imposta il valore della penna di primo piano al valore pen.

void SetBPen( struct RastPort *rp, unsigned long pen );
Imposta il valore della penna di sfondo al valore pen.

void SetOPen( struct RastPort *rp, unsigned long pen );
Imposta il valore della penna di contorno (utilizzata in alcune funzioni) al valore pen.

void SetDrMd( struct RastPort *rp, unsigned long drawMode );
Imposta il valore del modo di disegno al valore drawMode.
I modi possibili sono:

  • #define JAM1 0 /* jam 1 color into raster */
  • #define JAM2 1 /* jam 2 colors into raster */
  • #define COMPLEMENT 2 /* XOR bits into raster */
  • #define INVERSVID 4 /* inverse video for drawing modes */

WORD TextLength( struct RastPort *rp, STRPTR string, unsigned long count );
Calcola l'occupazione in pixel sulla RastPort rp, dei primi count caratteri della stringa string.

LONG Text( struct RastPort *rp, STRPTR string, unsigned long count );
Visualizza alla posizione attuale del cursore grafico count caratteri della stringa string utilizzando il carattere selezionato.

LONG SetFont( struct RastPort *rp, struct TextFont *textFont );
Modifica il carattere da usare con la RastPort rp con il font precedentemente aperto textFont.

struct TextFont *OpenFont( struct TextAttr *textAttr );
Carica il carattere descritto dalla struttura textAttr e lo restituisce.
La struttura TextAttr è così definita:

struct TextAttr {
         STRPTR  ta_Name;    /* name of the font */
         UWORD   ta_YSize;      /* height of the font */
         UBYTE   ta_Style;      /* intrinsic font style */
         UBYTE   ta_Flags;      /* font preferences and flags */
};

Un esempio di inizializzazione è:

struct TextAttr MyFont = {"helvetica.font",15,FS_NORMAL,FPF_DISKFONT};

I flags sono definiti in include:graphics/text.h

void CloseFont( struct TextFont *textFont );
Chiude il font precedentemente aperto tramite OpenFont o OpenDiskFont (della diskfont.library che vedremo in seguito).

ULONG AskSoftStyle( struct RastPort *rp );
Restituisce gli stili del carattere usato nella RastPort rp che non sono proprietà del carattere stesso ma calcolati via software.
Questi sono i bits validi per impostare la maschera enable per la funzione SetSoftStyle.

ULONG SetSoftStyle( struct RastPort *rp, unsigned long style, unsigned long enable);
Richiede uno stile software per il carattere usato dalla RastPort rp (grassetto italico, sottolineato).
I possibili stili sono:

  • #define FS_NORMAL 0 /* normal text (no style bits set) */
  • #define FSF_UNDERLINED 0x01 /* underlined (under baseline) */
  • #define FSF_BOLD 0x02 /* bold face text (ORed w/ shifted) */
  • #define FSF_ITALIC 0x04 /* italic (slanted 1:2 right) */
  • #define FSF_EXTENDED 0x08 /* extended face (wider than normal) */
  • #define FSF_COLORFONT 0x40 /* this uses ColorTextFont structure */
  • #define FSF_TAGGED 0x80 /* the TextAttr is really an TTextAttr, */

Anche se onestamente non ho mai usato gli ultimi tre.

Listato di questa lezione

Lezione precedente Indice delle lezioni Lezione successiva
Copyright AMiWoRLD Ph0ton