PETSCII 80 Converter

Recientemente nos donaron en el museo una maravillosa CBM PET 8032

Ya contábamos con otra PET, el modelo 4032, que son muy similares, pero la principal diferencia es el display: como sugiere el nombre, la 8032 tiene un display de 80 columnas, mientras que la 4032 solo tiene 40.

Si bien para la 4032 hay una variedad interesante de software (incluso modernos, como Attack of Petscii Robots), siendo la 8032 un modelo más “profesional” no encontré demasiado software, por lo que decidí comenzar a desarrollar algo para mostrar a los visitantes en esta máquina.

El principal problema que tengo es mi total incapacidad artística (y menos con caracteres PETSCII), por lo que se me ocurrió que podria armar un slideshow/animacion con PETSCII art, para lo cual tendria que utilizar algunos de los tantos utilitarios que convierten imagenes en petscii.

El problema que encontré fue que todos estos utilitarios generan PETSCII para la C64 y en 40 columnas (por lo que no me servían para generar pantallas para la 8032) tras lo cual decidí implementar yo mismo un conversor de imagen B&W a PETSCII.

El conversor toma una imagen en PNG, en 1 bit de profundidad de color, a una resolución de 640×200, y genera un archivo con los códigos que se pueden importar en cualquier compilador de assembler (aca voy a poner un ejemplo en kickassembler, el que utilizo yo).

Para utilizar el conversor lo mejor es utilizar algun software de edición de imágenes (ejempo: GIMP), ajustarla en tamaño a 640×400, luego la pasamos a B&W con 1 bit de profundidad de color (para eso mejor aplicar un filtro threshold, para evitar tramas). Finalmente reescalamos todo a 640×200 (la mitad de altura) sin aplicar ningun tipo de suavizado (nada de bilinear ni esas cosas, smoothing none), y lo guardamos como PNG.
Esta imagen “preprocesada” es la que vamos a usar como entrada en nuestro programa. 

El programa está escrito en Python 3, por lo que es requisito que esté instalado en nuestro sistema. Para utilizarlo simplemente escribimos “python convert.py <imagen_de_entrada.png> <output.raw>”, lo que nos generará un archivo de 2000 bytes, que es lo que ocupa una pantalla en la PET 8032.

Ejemplo de uso:

Supongamos que tenemos una imagen como esta:

entonces la llevamos a 640x400px. 

La razón de utilizar primero una resolucion de 640×400 y luego escalar verticalmente a la mitad es porque la “resolución” de pantalla de la pet es en realidad 640×200, pero los pixeles son el doble de altos que ancho, y para trabajar la imagen en el GIMP de manera que se visualice correctamente es mejor hacer todo en 640×400, y al final escalar a 640×200.

Una vez que acomodamos en tamaño, el siguiente paso es convertir esta imagen en B&W con 1 bit de profundidad de color. Para ello lo mejor es utilizar primero el filtro Threshold (disponible en todos los programas de edición de imágenes), ajustamos el slider hasta lograr el mejor resultado, y luego convertimos esta imagen a monocromo 1 bit. Esto es necesario porque simplemente en la PET no tenemos ningun color, ni escala de grises.


Queda un último paso, que es reescalar a la mitad, para que el software pueda realizar la conversión correctamente.

Para ello vamos a las opciones de Image Resizing de nuestro software, y reescalamos a 640×200 (quitamos el bloqueo de aspect ratio), y desactivamos todo tipo de suavización (nada de bilinear, trilinear ni esas cosas).

Exportamos esta imagen como PNG, y este lo utilizaremos como archivo de entrada con el conversor.


¿Por qué no hago todos estos ajustes automaticamente? Al fin y al cabo, la libreria PIL (tratamiento de imágenes en Python) permite hacer todo esto.

La razón es muy simple: Si automatizo estos pasos no tengo control sobre tamaños, ni ajustes de threshold, ni sobre qué efectos aplicar (a veces conviene por ejemplo aplicar un posterizado a 3 colores, y sobre eso realizar la conversion con un tramado por position), por lo que decidí que el programa SOLO realice la conversion del bitmap a characters, y el procesado que lo realice el usuario de la forma y con las herramientas que le parezcan.

Y como lo importamos en nuestro .asm?

Como mencionamos anteriormente, con “python convert.py image.png petscii.raw” convertimos la imagen a petscii. Luego podemos importarla y utilizarla como nos parezca. A continuación un ejemplo ultra sencillo:

 * = $0400 "Basic Upstart"
 // Esto basicamente escribe en BASIC lo siguiente: SYS 1050
.byte $00, $0c, $04, $0a, $00, $9e, $20, $31, $30, $35, $30, $00, $00, $00

* = 1050
main:
	// SETEAMOS EL SET DE CARACTERES MAYÚSCULAS
    ldx #12
    stx 59468 

    rts

* = 32768 "SCREEN"
.import binary "petscii.raw"

lo compilamos con kickassembler, cargamos el PRG en el vice (con el ejecutable xpet.exe), y obtenemos nuestra pantalla en PETSCII


y eso es todo…
el código del conversor lo pueden obtener de github: https://github.com/moonorongo/petsciiator80

Hasta el próximo post!