Convirtiendo y mostrando una imagen en pantalla (C con SDCC)

Click here to see in English

En este tutorial vamos a ver como convertir y mostrar en la pantalla una imagen de la manera más simple posible. Para evitar tener que cargar ficheros en el Amstrad CPC, vamos a incrustar la imagen en el propio binario ejecutable.

Para empezar vamos a buscar la imagen que queremos convertir, en mi caso voy a usar una de mi prima (que nadie me pida el teléfono):

rihanna

Para convertirla vamos a usar la estupenda herramienta ConvImgCPC. Yo la he configurado como se ve en la siguiente captura para conseguir el resultado que más me gustaba:

rihanna

Una vez tengamos el resultado que más nos guste vamos a exportar la imagen para poder usarla en nuestro programa, para ello seleccionamos la opción "asm mode" y pulsamos el botón "Save Picture" y guardamos como rihanna.asm (en este caso), para la paleta nos apuntamos los colores que aparecen abajo a la derecha (donde pone "16 most used colors").

Como el formato de salida de la imagen en asm no es directamente compatible con C, vamos a adaptarlo muy fácilmente, abrimos el fichero asm (rihanna.asm) en un editor de texto (block de notas, ultraedit, etc..) y buscamos la opción de "Reemplazar" (en el block de notas CTRL-R) y decimos que nos sustituya el carácter '#' por '0x' y pulsamos "Reemplazar todo", después le decimos que nos sustituya el texto 'DB' por ',' y pulsamos de nuevo "Reemplazar todo". Ya tenemos casi adaptado el fichero, hay que borrar la primera ',' y darle un nombre al array (const char RihannaScreen), es muy importante poner la palabra 'const' ya que si no la ponemos SDCC cargará cada dato mediante instrucciones LD. Finalmente añadimos la paleta, las llaves y grabamos el fichero como rihanna.h quedando de la siguiente manera:

/*
;Généré par ConvImgCpc Version 0.16
; Mode 0
; 80x200
*/
const unsigned char RihannaPalette[16] = {26,0,13,16,25,12,3,17,4,15,7,1,22,23,14,9};

const char RihannaScreen[] = 
{
               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51
        ,      0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0
        ,      0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0
        ,      0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0
        ,      0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0
        ,      0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xCA, 0xC0, 0xC0
        ,      0xC0, 0xC0, 0xC0, 0xC0, 0x48, 0xC0, 0xC0, 0xC0
        ,      0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x06, 0xE0
        ,      0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00
        ,      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
        ,      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
        ,      0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0
        ,      0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0
        ,      0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0
        ,      0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0
        ,      0xC0, 0xC0, 0xC0, 0xC0, 0xDA, 0xC0, 0xC0, 0xC0
        ,      0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0
        ,      0xC0, 0xC0, 0x48, 0xC5, 0xE0, 0x18, 0x1C, 0xC0
        ,      0xC0, 0xC0, 0xD0, 0x1C, 0x00, 0x00, 0x00, 0x00
        ,      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
        ,      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
        ,      0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0
        ,      0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0
        ,      0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0
        ,      0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0
        ,      0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0
        ,      0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0
        ,      0xC0, 0x84, 0x48, 0x84, 0x20, 0x48, 0xC0, 0xC0
        ,      0x48, 0x94, 0x98, 0x4C, 0x00, 0x00, 0x00, 0x00
        ,      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
        ,      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
        ,      0x3F, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0
        ,      0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0
        ,      0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0
        ,      0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0
        ,      0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0
        ,      0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x84
        ,      0xC0, 0x1C, 0xCC, 0x4C, 0xE0, 0xC0, 0xC0, 0x84

Montones de líneas más...

        ,      0x78, 0xF0, 0x49, 0x4C, 0xCC, 0x98, 0x98, 0x30
        ,      0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
        ,      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
        ,      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

 

Para mostrarlo en pantalla, hacemos un sencillo programa, que lo único que hace es pasar a modo 0, poner la paleta todo a negro, copiar la imagen a la memoria de video y finalmente poner la paleta real de la imagen, el programa quedaría así:

////////////////////////////////////////////////////////////////////////
// Image01.c
// Show a image
// Mochilote - www.cpcmania.com
////////////////////////////////////////////////////////////////////////
#include <string.h>

#include "rihanna.h"

#define NUM_COLORS 16

const unsigned char BlackPalette[NUM_COLORS] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

void SetColor(unsigned char nColorIndex, unsigned char nPaletteIndex)
{
  __asm
    ld a, 4 (ix)
    ld b, 5 (ix)
    ld c, b
    call #0xBC32 ;SCR SET INK
    __endasm;
}

void SetPalette(const unsigned char *pPalette)
{
  unsigned char nColor = 0;

  for(nColor = 0; nColor < NUM_COLORS; nColor++)
    SetColor(nColor, pPalette[nColor]);
}

void main()
{
  //SCR_SET_MODE 0
  __asm
    ld a, #0
    call #0xBC0E
  __endasm;

  //SCR SET BORDER 0
  __asm
    ld b, #0 ;black
    ld c, b
    call #0xBC38
  __endasm;

  SetPalette(BlackPalette);

  memcpy(0xC000, RihannaScreen, 0x3FFF);

  SetPalette(RihannaPalette);

  while(1) {};
}
////////////////////////////////////////////////////////////////////////

Si lo cargamos en un emulador veríamos lo siguiente:

animation

Podéis bajar un zip con todos ficheros (código fuente, bat's para compilar, binarios y dsk's) aquí: Convirtiendo_y_mostrando_una_imagen_en_pantalla.zip

 

www.CPCMania.com 2012