Lithographica

Un cuaderno más de Juan Antonio Fernández Madrigal

Las imágenes del ZX Spectrum

Julio25/2011

Pedazo de entrada retro-friqui que os espera ;)

De vez en cuando me da la nostalgia ochentera, habitualmente coincidiendo con la cercanía a las vacaciones de verano (no me preguntéis por qué), y con bastante probabilidad me da en lo relacionado con esa maravillosa máquina, el ZX Spectrum, con el que se nos descubrió un nuevo mundo a tantos niños y no tan niños de la época.

Normalmente la cosa se resuelve visitando una vez más WorldOfSpectrum, echando unas partidillas a mis adorados Xeno y Manic Miner, y pensando por enésima vez por qué aquel emulador de Spectrum que me hice en 1991 para un i286 no me dio por hacerlo diez años después, que seguro que podía haberlo terminado mejor (con mucha más documentación disponible de la que yo tuve); ahora podría estar incluido en la lista de emuladores.

En fin. Esta vez me ha dado la picá por otro lado. No sé cómo he acabado pensando que podría ser curiosón el poder convertir imágenes bitmap a la apariencia que tenían las imágenes en el ZX Spectrum, y, ya puestos, hacer un plug-in para el programa de diseño gráfico GIMP que haga esa transformación. Hay alguna utilidad por ahí relacionada con la conversión de imágenes del Spectrum, pero no algo como lo que propongo en forma de plug-in de GIMP. Así que, ni corto ni perezoso, me he puesto a la tarea :)

Las imágenes del ZX Spectrum en su modo gráfico original, es decir, sin usar hardware/software especial que consiguiera incrementar la resolución, eran bitmaps de 256×192 píxeles, con el píxel 0,0 en la esquina inferior izquierda si mal no recuerdo (estoy escribiendo de memoria). Estos píxeles no se podían poner a ningún color concreto, sólo a apagado (0) o encendido (1), lo que suponía 256×192/8=6144 bytes de información que estaban almacenados a partir de la dirección 16384 de la RAM, es decir, justo tras los primeros 16KB de la ROM del sistema.

El color era el verdadero meollo de la historia de los gráficos de Spectrum. La paleta del ZX (de la que ya hablamos por aquí) tenía 8 colores, algunos de los cuales se observan en la esquina inferior derecha de la carcasa de la foto de arriba. Si Sir Clive Sinclair hubiera querido que pudiéramos especificar uno de esos 8 colores por cada píxel del bitmap, a tres bits por píxel, hubiera gastado un total de 256x192x3/8=18432 bytes de memoria para la imagen de pantalla, en lugar de los 6144 del blanco y negro. Definitivamente, 18KB era algo prohibitivo para la época, especialmente teniendo en cuenta que la RAM del Spectrum era de 48KB: con esa capacidad gráfica sólo hubieran quedado 30KB para variables del sistema, programas del usuario y pila de la CPU. Pero mucho peor: hubiera habido bastantes problemas de rendimiento a la hora de que una CPU Z80A a 3.47MHz direccionara los píxeles y no digamos ya de que hiciera animación, por mucho que yo siga admirando a esa CPU.

La solución no pudo ser más ingeniosa, a la par que enrevesada a la hora de su uso posterior: dividamos los 256×192 píxeles en celdas de 64 píxeles cada una (de 8×8 píxeles, para ser exactos), y asignemos un byte extra a cada celda, llamado “atributo”, que indique el color que tienen los píxeles de esa celda que estén a 0 -píxeles de “papel”- y el que tienen los píxeles que estén a 1 -píxeles de “tinta”. Además, al dividir la imagen en celdas de 8×8 podemos montar un modo texto además del modo gráfico, con sus rutinas específicas: en cada celda se podrá dibujar un carácter, pudiendo tener en pantalla 24 líneas por 32 columnas de texto. Bondadoso que es el destino: si dedicamos 1 byte al atributo de cada celda, dado que especificar un color, ya sea el de tinta o el de papel, ocupa 3 bits, nos quedan todavía 2 bits libres para jugar. Uno de ellos se dedicó al “brillo”, y otro al “parpadeo”. El esquema final de un byte cualquiera de atributo quedó así:

Lo del brillo es otra genialidad: con ese bit a 1 cualquier atributo podía indicar que los colores de papel y tinta no vinieran de la paleta original, sino de otra que contenía los mismos colores pero con más brillo -excepto el negro, que era el mismo-, es decir, que con el bit de brillo prácticamente se duplicaban los colores disponibles en la pantalla, con la salvedad de que no se podía usar un color con brillo y otro sin brillo en la misma celda.

Lo del parpadeo tenía también su enjundia: con otro bit por celda se podía hacer que el color que en ésta estaba asignado a la tinta pasara a ser mostrado en los píxeles de papel, y viceversa, intermitentemente (con una frecuencia de 1Hz, si tampoco recuerdo mal), todo eso sin necesidad de que el programador cambiara nada en memoria, puesto que lo realizaba automáticamente la ULA (uncommitted logic array), la circuitería gráfica del Spectrum. Esto del parpadeo puede parecer una tontería de poca utilidad, pero imaginad qué pasa si relleno algunas celdas de la pantalla con todos sus píxeles en tinta, otras con todos sus píxeles en papel, y activo el parpadeo: puedo montarme un cartel -con poca resolución, eso sí- que va cambiando de apariencia intermitentemente, es decir, puedo tener dos imágenes que se turnan en pantalla alegremente.

Se puede ver precisamente este efecto del parpadeo a partir del segundo 10 del siguiente vídeo, grabado del juego ya mencionado Manic Miner. También se observa claramente el típico aspecto de los gráficos del ZX Spectrum. El pedazo de borde que rodea a la imagen de pantalla estaba en principio desperdiciado: sólo se podía poner a un color, aunque si variabas ese color lo suficientemente rápido, como por ejemplo hacía la ROM mientras cargaba un programa en memoria desde la cinta de cassette, podías conseguir efectos muy curiosos.

En resumen: tenemos 6144 bytes que guardan qué píxeles de la imagen son papel y cuáles son tinta, y además otros 768 bytes a continuación de éstos, correspondientes a las 768 celdas de 8×8 píxeles que hay en una imagen de 256×192 píxeles, los cuales definen los atributos de color. El total es 6912 bytes, casi 7KB, para toda la imagen (bueno, 3 bits más si contamos el color del borde ;P), lo cual es absolutamente óptimo en términos de tamaño en memoria, funcionalidad gráfica y potencia de procesamiento. El ZX Spectrum introdujo verdaderas genialidades para su época, y este modo gráfico, por muy ridículo que nos parezca hoy en día, fue una de ellas.

Respecto al plug-in de GIMP que he escrito para transformar el aspecto de cualquier bitmap al de una imagen del ZX Spectrum no hay tanto que contar… Es fácil hacer plug-ins para GIMP, especialmente sobre sistemas Linux (GIMP también tiene versiones para otros sistemas) y programando en C. Aquí hay un tutorial que demuestra lo sencilla de usar que es la API de GIMP: te da un entorno de ejecución bastante completo donde se puede acceder a la imagen en curso.

El plug-in requiere que la imagen original sea RGB (no lo he probado pero está supuestamente preparado para trabajar también con imágenes que tengan canal de transparencia). La resolución de ésta no importa, aunque para tener una experiencia cercana a la de un verdadero ZX Spectrum es interesante reducirla primero de tamaño, concretamente a 256 píxeles de ancho (el alto da bastante igual), antes de aplicar el filtro. El plug-in se instala a sí mismo en una nueva carpeta de filtros de GIMP llamada “ZX” y no requiere ningún parámetro antes de ejecutarse. Hace la conversión directamente sobre la imagen, y usa una paleta de colores que he comprobado que es bastante parecida a la original del ZX. Incluso lo he probado sobre capturas de pantalla de emuladores del Spectrum y he validado que no cambia su contenido.

El algoritmo tiene su intríngulis porque hay que tomar algunas decisiones a la hora de reducir la gama de colores de la imagen inicial. Para empezar, se trata cada celda de 8×8 de la imagen inicial por separado (pueden sobrar píxeles en los bordes si el tamaño de la imagen original no es múltiplo de 8; éstos se mostrarán en negro). Dentro de cada celda se calcula qué color de la paleta del ZX Spectrum es más cercano al color del píxel en la imagen original, usando para ello la distancia cartesiana en el espacio tridimensional de coordenadas RGB. Tras esa conversión de color se hace un histograma para ver qué color del Spectrum aparece más frecuentemente dentro de la celda, y también cuál es el segundo más frecuente. El primero será el de tinta y el segundo el de papel -esta elección es arbitraria. Todos los píxeles de la celda que no sean del color de tinta ni del de papel serán convertidos al color de esos dos que quede más cercano en el espacio RGB. Finalmente está la decisión sobre el brillo (el parpadeo no se trata). Si ambos colores de la celda tienen el mismo brillo no hay que hacer nada. Si no, hay que cambiar uno para que tenga el mismo brillo que el otro porque sólo está permitido tener los dos con brillo o los dos sin brillo. Si uno de ellos es negro se le cambia el brillo a ése para que coincida con el brillo del otro y ya está, ya que el negro con brillo es el mismo color que el negro sin brillo. Si no es el caso, se le cambia el brillo al color que sea menos frecuente en la celda, en nuestro caso al papel. Voilà :)

Obviamente, se puede enriquecer este algoritmo con muchísimas cosas, principalmente para tener en cuenta la imagen completa y no por celdas separadas, ya que esto podría mejorar mucho la apariencia final al tomar decisiones que dependieran de la distribución global de los colores. Esto lo dejo para cuando tenga ganas de escribir el paper “Back to eighties: a new approach to draw ZX Spectrum bitmaps from RGB images” y mandarlo a algún sitio donde me lo rechacen inmisericordemente por irrelevante XDD (lástima que no exista ninguna IEEE Transactions on Freak Stuff indexada para el currículum ;P).

En este enlace podéis descargar el código fuente del plug-in. No he tenido ningún cuidado con la estructura ni elegancia del programa (aunque está bastante documentado), así que no respondo si se os caen las pestañas pensando cómo he podido hacer tal guarrerida programatística. Era pa jugar un ratillo ;) Para instalarlo en una máquina con Linux sólo hay que instalar previamente la librería de desarrollo de GIMP (libgimp-dev, típicamente en los repositorios) y luego usar la herramienta “gimptool-2.0″ desde línea de comandos como se explica en el mismo código fuente del plug-in.

Aquí dejo algunos ejemplos de lo que se puede conseguir (el último está ligeramente manipulado ;P). Podéis darle al Ctrl+ varias veces en vuestro Firefox para apreciar mejor los detalles:









Nostalgia (II)

Julio8/2011

El PC con el que me hice la beca de investigación (y la tesis doctoral):

¡Un pedazo i486 DX4 a 100MHz! El cual sufrió inicialmente el inefable Windows 95, en medio el rudo pero fiable LynxOS y no recuerdo si pudo con el Windows 2000… terminando su vida útil como PC chatarra para meterle antiguas tarjetas de adquisición de datos, y jubilándose finalmente como parte del mobiliario universitario ;)

Lagrimones como puños, oiga.

Nostalgia

Julio1/2011

Son ya 27 añitos desde el primero de éstos…

Eaolsndruitcpm

Mayo9/2011

Puede ser que algún día escriba una entrada al regresar del trabajo y me salga algo como lo de arriba, especialmente si me da por ahí un jueves del segundo cuatrimestre a las diez de la noche; pero no, esta vez no es fruto de una conexión espontánea del centro cerebral del lenguaje escrito con el plexo neuronal encargado de dar forma a las emociones primarias contra los partidos políticos.

Eso de ahí arriba es la frecuencia de uso, en perfecto orden de mayor a menor, de las letras en lenguaje escrito. No sabría decir si en castellano (creo que sí) o en inglés (pudiera ser), dado que me lo sé de memoria desde que tenía unos quince años y lo leí en un libro que había en el antiguo PRYCA (PRecio Y CAlidad) que no quería comprar por no hacer gasto y que por tanto no conservo. Ni siquiera recuerdo de qué iba el libro, pero el poder saber matemáticamente las letras que más se usan fue algo que me impactó bastante (a la vista está). Por aquel entonces no sabía nada del amigo Shannon y su teoría de la información, que da mucho juego y queda muy vistosa para este tipo de cosas.

Pues el caso es que me he acordado de esa secuencia de letras porque el otro día estaba concentrado escribiendo con el teclado, al que le empieza a fallar el blanco de las pegatinas de las teclas, y en vez de pensar, como siempre, “vaya mierda de pegatinas de las teclas”, pensé “leñes, de aquí se deduce algo”. He aquí el teclado en cuestión:

Como se ve, no sólo está el hecho de que las pegatinas son una mierda, sino el de que no todas están gastadas por igual. Las más gastadas parecen ser: e, a, s, d, i, l, m, que fue lo que me recordó el “eaolsndruitcpm” de esta entrada. También podemos ponernos técnicos y hacer una detección de bordes de esa imagen para ver dónde se detectan mejor, aunque realmente dependerá mucho el resultado del método elegido (yo lo he hecho con el operador de Sobel que viene con el GIMP), y al final creo que es más razonable fiarse de la capacidad de procesamiento de imágenes del cerebro. Esto es lo que obtenemos con el Sobel:

En fin. Que asumiendo un tiempo de uso no demasiado largo del teclado (de ahí mi afirmación de que las pegatinas son una mierda), y por tanto una incertidumbre más o menos elevada en la coincidencia de lo gastado con lo predicho teóricamente, tenemos que la coincidencia observada no está nada mal.

Mi santa me dijo luego que hay una historia de Sherlock Holmes parecida a todo esto. Qué de cosas pueden salir de una mirada perdida en medio de una labor rompeneuronas…

De cómo aprendí con el ZX Spectrum: teoría del color

Mayo2/2011

Yo con catorce años no sabía nada de teoría del color. Algún detallito que me habían enseñado en esa asignatura que entonces se llamaba “Pretecnología” (que era muy “Pre” porque no se usaba ni Photoshop ni nada para hacer las manualidades) sobre los colores “cálidos” y los colores “fríos”, pero poco más.

Entonces me regalaron un ZX Spectrum: un artilugio maravilloso que no sólo me llevó a estudiar lo que estudié y a trabajar en lo que trabajo, sino que me permitió aprender tantas cosas que me sigo maravillando de ello aún hoy. Y ya han pasado unos añitos.

Por ejemplo: el sistema de color del ZX constaba sólo de 8 colores distintos (luego empleados en ordenadores más sofisticados), a saber:

Índice Color Muestra
0 Negro
1 Azul
2 Rojo
3 Morado (magenta)
4 Verde
5 Celeste (cyan)
6 Amarillo
7 Blanco

También tenía otros ocho que eran estos mismos con brillo, y un sistema de mostrarlos en pantalla bastante enrevesado que sin embargo tenía un par de buenas ventajas: ahorraba mucha memoria (768 bytes para 256×192=49152 píxeles) y fomentaba una jartá la imaginación de los diseñadores de programas para que no se notara el tremendo pixelado de los colores. Pero ésas son otras historias.

Vista esa tabla de colores como está arriba no parece gran cosa, ni que eso suponga que un niño aprenda nada del otro jueves. Pero veamos qué pasa si añadimos el número de cada color en binario:

Índice Binario Color Muestra
0 000 Negro
1 001 Azul
2 010 Rojo
3 011 Morado (magenta)
4 100 Verde
5 101 Celeste (cyan)
6 110 Amarillo
7 111 Blanco

Fijaos qué cosa más curiosa: en binario, se puede interpretar que el número es como una serie de tres interruptores, cada uno encendiendo (si está a 1) una luz de un color “básico”, o apagándola (si está a 0). Concretamente, podemos deducir de la tabla anterior los siguientes colores “básicos” asignados a cada uno de los tres bits:

Bit Luz
0 (menos significativo, o sea, más a la derecha) Azul
1 (en medio) Roja
2 (más significativo, o sea, más a la izquierda) Verde

Visto de esta manera, está claro que si no encendemos ninguna de estas luces “básicas” tenemos ausencia total de color (=negro), si las encedemos todas tenemos el color más luminoso (=blanco), y si encendemos sólo algunas tenemos una mezcla de “luces básicas” que da otra luz que ya no es básica:

Índice Binario Color Mezcla
0 000 Negro (ningún color)
1 001 Azul (color “básico” puro)
2 010 Rojo (color “básico” puro)
3 011 Morado (magenta) Rojo+Azul
4 100 Verde (color “básico” puro)
5 101 Celeste (cyan) Verde+Azul
6 110 Amarillo Verde+Rojo
7 111 Blanco (todos los colores)

Es decir: que la mezcla de luz roja y azul da una luz morada; la de verde y azul, celeste; la de verde y roja, amarilla. Que es exactamente lo que pasa en la realidad física. En teoría del color, los colores verde, rojo y azul (ésos tan conocidos en las teles y monitores por sus siglas RGB), en el contexto de luces que se emiten con esos colores, se llaman primarios, porque no son mezcla de otros. Los que sí lo son, concretamente de dos primarios, se llaman colores secundarios, formando así una especie de operación aditiva matemática (commutativa) de los colores1.

No es poca cosa todo esto para haberlo aprendido sin darme cuenta -mientras aprendía otras muchas de las que sí me daba cuenta- y para haberme servido luego en multitud de ocasiones. De hecho, ahora recuerdo perfectamente de memoria el índice de cada uno de los colores del ZX, simplemente porque recuerdo que el azul es el 1, el rojo el 2 y el verde el 4 (potencias de dos). Como el resto son sumas de ésos, y sé que el morado es azul más rojo, su número en el ZX tenía que ser forzosamente el 3.

También recuerdo de memoria números como 16384, 6144, 768, 6912, 17, 65536, 32768, 49152, 23728-23729, 23552, 256 y otros que aprendí mientras jugaba con el Spectrum. Como he dicho antes, cada uno de ellos también tiene su historia :)



1 En el caso de la luz reflejada (que no emitida), la aditividad del color es distinta, e incluso los colores primarios cambian: básicamente, un pigmento es de un color determinado porque refleja hacia tus ojos la luz de ese color, absorbiendo el resto, así que si le añades otro pigmento que absorba luces de colores diferentes a los que absorbe el primero, tienes bastantes posibilidades de recibir en tus ojos menos luz en total: ése es el motivo por el que la mezcla de muchos pigmentos diferentes da un pigmento negro (al contrario que la mezcla de muchas luces emitidas diferentes, que da una luz emitida blanca).

No sólo pasa en la industria del videojuego

Marzo22/2011

Tras pocos años en el mundo del desarrollo videojueguil, Menéndez descubrió que lo importante no era la creatividad ni la técnica, sino el negocio puro y duro. Vamos, que se dio de bruces contra la realidad.

Artículo sobre Paco Menéndez, uno de los creadores de videojuegos más importantes de la época del ZX Spectrum

16’5 años después…

Septiembre4/2010

No voy a decir ná, que no me gusta hablar hasta que no termino las cosas, pero ya me hace ilu poder comparar lo que había hace más de dieciséis años:

Con lo que va empezando a haber ahora, a base de vacaciones y ratos libres:

P.D.: Dedicado al Hombre Mecatrónico Temporalmente Inglés, y a J.C. Vega. Que sepáis que, aparte de tener mucha culpa en todo esto, lo que había hace más de dieciséis años es aún una de las mejores implementaciones posibles ;)

La dicotomía Batman-Supermán es poderosa

Junio9/2010

En particular, sirve de soporte a un buen número de analogías.

Por ejemplo, los de mi edad estarán de acuerdo en que la serie Comando G era a la serie Mazinger Z como… Batman a Supermán. Mucho más misteriosa, oscura, complicada… Vamos, sólo los niños que ya estábamos de vuelta de los patios de colegio pavimentados de hormigón armado y de los pupitres astillados podíamos entender Comando G y el sobrehumano esfuerzo que reflejaban los rostros de los protagonistas: es que tenían que defender nuestra galaxia entera.

(Enlace al vídeo)

Cuando jugábamos de niños, yo siempre quería ser Jason, porque, además, Jason era a Mark como… Batman a Supermán.

Las versiones alternativas de las historias de superhéroes…

Junio1/2010

…no han sido inventadas hace poco, no. Los niños de los 80, que vivimos la década más creativa de todas las décadas de la humanidad en cuanto que es y que no nos lo discuta nadie, sabemos desde hace mucho que los (super)héroes tienen una vida propia además de salvar a la humanidad y a las viejecitas, que sus poderes son utilizables y comprensibles hoy sí y mañana no, y que en su mayoría son unos perfectos inadaptados que tienen que llevar las mallas al tinte:

(Enlace al vídeo.)

Así empezó todo…

Marzo25/2010

Hace ya 25 añitos de mi primer ordenador (el pequeñito de la foto), 24 desde mi primer lenguaje serio aprendido (ensamblador del Z80), y algo así como una historia a las espaldas de dedicación a la labor de crear pequeños mundos llenos de reglas que les hagan funcionar solos.

Y luego se preguntan por las similitudes entre programar, investigar y escribir novelas…

« Antiguas
  • Últimas lecturas:

  • Andanzas artísticas:

  • Criaturas:

  • Creative Commons License