Indice

LE BASI DELLE BITMAP IN MIDRES

DEFINIRE UNA BITMAP MIDRES

La base di questa tecnica, che ha a che vedere con una grafica di tipo “bitmap” ovvero “bianco / nero” (1 bit), si basa sullo stabilire a priori uno schema di indirizzamento di tutti i punti disponibili alla risoluzione massima disponibile sull'hardware (chiamata convenzionalmente “hires”).

Questo schema è organizzato secondo un principio di “raggruppamento” di pixel a matrice, sottomultiplo della dimensione del carattere alla risoluzione minima disponibile, ovvero quella testuale (chiamata convenzionalmente “lowres”).

Questo processo permette di raggiungere una risoluzione intermedia, a cui viene dato convenzionalmente il nome di “midres”.

LA MIDRES NEL COMMODORE 64

Ad esempio, nel Commodore 64 abbiamo che lo schermo testuale consta di 40 colonne per 25 righe. Ogni carattere occupa una matrice di 8×8 pixel.

Ne consegue che la risoluzione massima (“hires”) è pari a 320×200 pixel mentre quella minima (“lowres”) è di 40×25. Un carattere grande 8×8 pixel potrebbe essere diviso verticalmente in due metà e orizzontalmente in altrettante parti.

Raggruppando quindi i pixel a 4 a 4, otteniamo che ogni carattere di 8×8 pixel da spazio a una matrice di 2×2 “punti”, che altro non sono che i pixel a media risoluzione (che chiameremo “midres pixel” = “mixel”). In tal modo otteniamo uno schermo avente risoluzione pari a 80×50 pixel.

Si può quindi pensare di assegnare un colore bianco al bit 1 e un colore di nero al bit 0. Poiché vi sono 4 “mixel” indipendenti per ogni matrice, e visto che possono essere accesi o spenti in modo indipendente, sono possibili ben 2^4 = 16 combinazioni.

Tale corrispondenza è implementata per mezzo di un indice corrispondente alla posizione nella mappa dei caratteri di una matrice dei relativi punti.

Per rappresentare tale varietà si utilizzerà, quindi, un insieme di caratteri speciali, che rappresentano visivamente e in maniera esaustiva tutte le combinazioni binarie di tale matrice di suddivisione. Detto in altri termini: ogni “mixel” viene rappresentato da un gruppo di 4×4 pixel ad alta risoluzione, e ogni 2×2 mixel è rappresentato da uno specifico carattere.

USARE IL PETSCII

Tali simboli, che appaiono esattamente come se fossero disegnati in modalità grafica raster, sono chiamati caratteri pseudografici e sono, in genere, parte integrante del set di caratteri di molti retrocomputer1).

In particolare nel Commodore 64 (e di tutta la famiglia di computer Commodore) abbiamo a disposizione 16 caratteri già pronti, e presenti nell'alfabeto PETSCII. Questo implica che è possibile visualizzare questi caratteri sin dal momento in cui viene acceso il computer, anche quando non è ancora stato caricato alcun programma.

DISEGNARE UN MIXEL

Disegnare un mixel è un processo più elaborato che disegnare un pixel e questo a causa della necessità di dover selezionare uno tra i caratteri speciali che rappresentino quella specifica combinazione di mixel per quel determinato blocco.

Si comincia individuando le coordinate del carattere sullo schermo a cui afferisce il mixel che si vuole disegnare alle coordinate (x,y). Supponendo di operare con un carattere da 8×8 pixel e con una matrice da 2×2 mixel per carattere, il carattere si ottiene dividendo le coordinate per 2:

  mx = _x >> 1;
  my = _y >> 1;

A questo punto è necessario individuare a quale mixel, tra i quattro che compongono il carattere, si è interessati a disegnare. I mixel sono convenzionalmente rappresentati secondo il diagramma sopra rappresentato.

Quindi se il mixel da colorare si trova su una ascissa pari, esso sarà rappresentato dalla lettera a oppure c; al contrario, se l'ascissa è dispari, sarà rappresentato dalla lettera b oppure d. Al contempo, se l'ordinata è pari, sarà rappresentato dalla lettera a oppure b; al contrario, dalla lettera c oppure d. L'intersezione tra questi due insiemi di lettere costituisce il bit da abilitare. Tale bit appartiene al nibble (4 bit) meno significativo del byte che si andrà a comporre.

    abcd = ((1 - (_x & 1)) + (1 - (_y & 1)) * 2);

A questo punto è possibile procedere a disegnare effettivamente il carattere grafico. A tal fine è necessario conoscere quale sia il carattere occupato dalle coordinate attuali, per decodificarne l'attuale pattern.

  for (i = 0; i < sizeof(RENDERED_MIXELS); ++i) {
    if (RENDERED_MIXELS[i] == _current) {
      return i;
    }
  }

A tale scopo il sistema consulterà l'insieme dei caratteri speciali, per individuare quale sia la configurazione attuale dei pixel.

  currentMixelbits = currentMixelbits | (1 << _abcd);

Una volta individuata la configurazione, si imposterà il relativo bit individuato dalle coordinate.

  return RENDERED_MIXELS[currentMixelbits];

Infine, si utilizzerà il nuovo carattere speciale così individuato, per sostituirlo al precedente.

EXAMPLE

Si prenda, ad esempio, la seguente immagine PNG (800×500 pixel, 1 bpp):

Si può utilizzare il programma img2midres per convertire tale immagine in due file (-o, -O) direttamente caricabili in memoria (-u) con una bitmap midres in bianco e nero (-b) per il Commodore 64 (-64):

  img2midres64.exe -64 -b -u -i image05.png -o image6405b.pic -O image6405b.col

Una volta inseriti i due file in un disco, sarà possibile scrivere un breve programma BASIC:

  10 if p=0 then 50
  20 if c=0 then 60
  30 poke 53281,0
  40 goto 40
  50 p=1:load "image6405b.pic",8,1
  60 c=1:load "image6405b.col",8,1
  

Questo è il risultato che si ottiene:

Se invece si possiede un Commodore VIC 20, si può utilizzare il programma img2midres per convertire tale immagine in due file (-o, -O) direttamente caricabili in memoria (-u) con una bitmap midres in bianco e nero (-b) per il Commodore VIC 20 (-20):

  img2midres64.exe -20 -b -u -i image05.png -o image2005b.pic -O image2005b.col

Una volta inseriti i due file in un disco, sarà possibile scrivere un breve programma BASIC:

  5 if i=0 then 45
  10 if p=0 then 50
  20 if c=0 then 60
  30 poke 36879,8
  40 goto 40
  45 for i=0 to 23*22:print " ";:next i
  50 p=1:load "image2005b.pic",8,1
  60 c=1:load "image2005b.col",8,1

Questo è il risultato che si ottiene:

USING OTHER HARDWARE

A seconda dell'hardware utilizzato, poi, possono essere presenti caratteri semigrafici analoghi oppure può essere necessaria una operazione preventiva di riprogrammazione dell'hardware video, per convertire il set di caratteri al fine di riprodurre il modello di bit così come descritto.

In alcuni hardware il numero di caratteri necessari potrebbe essere dimezzato in presenza di un attributo “reverse”, in quanto metà dei caratteri sono l'inverso logico dell'altra metà.

Altri trucchi usati per diminuire il numero di caratteri necessari sono:

1)
Questo approccio è stato poi adottato, in tempi successivi, nello standard UNICODE come ad esempio nel blocco Unicode Block Elements.
2)
L'utilizzo del carattere 0x7f esadecimale (decimale 127) per indicare “tutti i pixel a uno” è legato alla natura dei nastri perforati: infatti, quando si utilizzava il nastro, perforandolo per rappresentare l'informazione, con quel valore venivano punzonati tutti e sette i fori, creando il “byte” esadecimale 0x7f, considerato un altro modo per cancellare il carattere. Successivamente, lo stesso codice fu usato dai progettisti dei sottosistemi grafici per rappresentare il cursore sullo schermo.