viernes, 24 de mayo de 2024

Commodore 64C: Caracteres Multicolor

En el artículo anterior expliqué como programar un juego para el ordenador Commodore 64C. En este artículo voy a añadir al juego un fondo multicolor utilizando caracteres personalizados. Al igual que con los sprites se pueden crear dos tipos de caracteres: alta resolución y un solo color o baja resolución con tres colores. Estos caracteres personalizados nos pueden servir para añadir más letras o signos de puntuación y también los podemos utilizar para dibujar gráficos.

Los caracteres están formados por una matriz de 8x8 puntos y ocupan 8 bytes. En los caracteres de alta resolución se utiliza un bit por cada punto, por lo que cada punto tiene dos estados: transparente o color. En los caracteres de baja resolución se agrupan los puntos de dos en dos y se utilizan dos bits por cada pareja de puntos. Esto reduce la resolución horizontal a la mitad pero permite que cada pareja de puntos tenga cuatro estados: transparente o tres colores. De los tres colores dos son comunes a todos los caracteres y uno es individual. El ordenador permite mostrar a la vez caracteres monocromo y multicolor. Para distinguirlos se utiliza el color individual. De 0 a 7 para caracteres monocromo y de 8 a 15 para caracteres multicolor.

Si el valor de los bits es 00 la pareja de puntos es transparente y tiene el color del fondo de la pantalla. Si el valor es 01 o 10 tienen el color definido en los registros 53282 y 53283. Por último si el valor es 11 los puntos tienen el color individual asignado en la RAM de color, bloque de memoria 55296–56295. Para dibujar una pista de color verde con líneas blancas he creado cinco caracteres multicolor. Solo he necesitado utilizar los dos colores comunes, uno para el verde y otro para el blanco.

Primero he creado un carácter con todos los puntos de color verde para los lugares donde no hay líneas. Las líneas laterales se dibujan con dos caracteres con una línea que cruza de esquina a esquina y la línea horizontal-superior se dibuja con caracteres que tienen una línea abajo que conecta con las líneas laterales.

La pantalla tiene 40 caracteres de ancho, numerados de 0 a 39. Al ser un número par no hay un carácter central y es necesario dibujar la línea vertical-central con los caracteres 19 o 20. Yo he creado una carácter con una línea vertical a la derecha para dibujar la línea con el carácter 19.

Cada línea de puntos del carácter forma un byte. Para utilizar los caracteres en BASIC se convierte el valor de cada uno de los bytes a decimal y se utilizan como parámetros de un comando DATA. A continuación se muestran los caracteres con las parejas de puntos/bits coloreados y la conversión a decimal de las líneas/bytes.

Fondo Verde
01010101= 85
01010101= 85
01010101= 85
01010101= 85
01010101= 85
01010101= 85
01010101= 85
01010101= 85

Línea Izquierda
01010110= 86
01010110= 86
01011001= 89
01011001= 89
01100101= 101
01100101= 101
10010101= 149
10010101= 149

Línea Derecha
10010101= 149
10010101= 149
01100101= 101
01100101= 101
01011001= 89
01011001= 89
01010110= 86
01010110= 86

Línea Horizontal-Superior
01010101= 85
01010101= 85
01010101= 85
01010101= 85
01010101= 85
01010101= 85
10101010= 170
10101010= 170

Línea Vertical-Central
01010110= 86
01010110= 86
01010110= 86
01010110= 86
01010110= 86
01010110= 86
01010110= 86
01010110= 86

Los caracteres al tener menos puntos que los sprites es más fácil crearlos manualmente, pero al igual que con los sprites también existen editores que nos permiten dibujar caracteres o gráficos compuestos por varios caracteres.

El juego de caracteres que utiliza el ordenador se encuentra en una memoria ROM, por lo que no podemos modificar los caracteres. Para utilizar nuestros propios caracteres es necesario copiar el juego de caracteres a la memoria RAM e indicar al ordenador que utilice esta copia. En la memoria RAM podemos cambiar alguno de los caracteres por los que creemos nosotros. Para hacer la copia se deben desactivar las interrupciones y hacer accesible la memoria ROM del juego de caracteres al procesador, en el bloque 53248-57343, mediante bank switching. Estas operaciones se realizan modificando los registros 56334 y 1.

A continuación podemos copiar la memoria ROM a un bloque de 4096 bytes de la memoria RAM que no estemos usando para sprites u otro propósito. Una vez copiada la memoria debemos revertir los cambios hechos en los registros 56334 y 1 para que el ordenador pueda funcionar normalmente. Por último hay que indicar en el registro 53272 el bloque de la memoria RAM donde se ha copiado el juego de caracteres con un número del 0 al 15. La dirección inicial del bloque de memoria RAM se calcula multiplicando el número de bloque por 1024. Si el bloque es 14 la dirección de memoria es 14 x 1024 = 14336.

6010 CB=14
6020 CC=CB*1024

6040 POKE 56334,PEEK(56334) AND 254                    
6050 POKE 1,PEEK(1) AND 251               
6060 FOR X=0 TO 4095: POKE CC+X,PEEK(53248+X): NEXT X 
6070 POKE 1,PEEK(1) OR 4                                
6080 POKE 56334,PEEK(56334) OR 1                     
6090 POKE 53272,PEEK(53272) AND 240 OR CB

El ordenador tiene dos modos de texto: mayúsculas/gráficos y minúsculas/mayúsculas. Cada modo tiene 128 caracteres y por cada carácter hay un carácter inverso, lo que hace un total de 256 caracteres por modo. Entre los dos modos suman 512 caracteres. Como cada carácter ocupa 8 bytes, en total se necesitan 512 x 8 = 4096 bytes de memoria para todos los caracteres.

Una vez copiado el juego de caracteres podemos sustituir caracteres que no necesitemos por los que hemos creado. Por ejemplo yo he sustituido los últimos 5 caracteres del modo mayúsculas/gráficos, del 123 al 127.

6100 FOR X=CC+(123*8) TO CC+(127*8)+7: READ Y: POKE X,Y: NEXT X

20000 DATA 85,85,85,85,85,85,85,85
20010 DATA 86,86,89,89,101,101,149,149
20020 DATA 149,149,101,101,89,89,86,86
20030 DATA 85,85,85,85,85,85,170,170
20040 DATA 86,86,86,86,86,86,86,86

Para utilizar caracteres multicolor hay que activar en el registro 53270 el modo de caracteres multicolor. En el registro 53282 se asigna el color verde para el fondo de la pista y en el registro 53283 el color blanco para las líneas. Aunque no se utilice el color individual es necesario asignar un color individual de 8 a 15 en el bloque de memoria 56096-56295 para indicar que los caracteres son multicolor.

6110 POKE 53270,PEEK(53270) OR 16
6120 POKE 53282,5
6130 POKE 53283,1
6140 FOR X=56096 TO 56295: POKE X,8: NEXT X

La pantalla se compone de 40x25 = 1000 caracteres. Cada uno de los caracteres de la pantalla tiene asignado un byte del bloque de memoria 1024-2023. Para dibujar gráficos utilizando caracteres podemos utilizar los comandos PRINT y CHR$ o escribir directamente en memoria con el comando POKE el número del carácter. Según lo que queramos hacer nos puede resultar más fácil con uno u otro método. Si usamos el comando CHR$ hay que tener en cuenta que utiliza los códigos PETSCII y no se corresponden con los números usados en la memoria. Por ejemplo para imprimir el carácter 123 debemos utilizar el código PETSCII 187.

PRINT CHR$(187)

Yo he optado por escribir directamente en memoria para dibujar la pista. Primero utilizo el carácter 123 para poner en verde todos los caracteres entre el 1824 y 2023. A continuación utilizo el carácter 124 entre el carácter 1867 y 1984 para dibujar la línea de la izquierda. Entre cada carácter se saltan 39 caracteres, uno menos de los 40 de cada línea para que cada carácter quede a la izquierda del anterior. Para dibujar la línea de la derecha se hace algo similar, se imprime el carácter 125 entre los caracteres 1900 y 2023 con saltos de 41 caracteres para que cada carácter quede a la derecha del anterior. La línea horizontal superior se dibuja entre los caracteres 1828 y 1859 con el carácter 126. Para finalizar se dibuja con el carácter 127 la línea vertical-central entre los caracteres 1883 y 2003 con saltos de una línea completa de 40 caracteres.

6150 FOR X=1824 TO 2023: POKE X,123: NEXT X 
6160 FOR X=1867 TO 1984 STEP 39: POKE X,124: NEXT X
6170 FOR X=1900 TO 2023 STEP 41: POKE X,125: NEXT X
6180 FOR X=1828 TO 1859: POKE X,126: NEXT X
6190 FOR X=1883 TO 2003 STEP 40: POKE X,127: NEXT X

Como la copia del juego de caracteres desde la ROM a la RAM tarda bastante, antes de hacer la copia podemos comprobar si ya se ha realizado anteriormente y no es necesario volver a hacerla. De esta forma si volvemos a ejecutar el juego con el comando RUN tardará menos en iniciarse.

6030 IF PEEK(CC) > 0 THEN GOTO 6140

El código para dibujar la pista se encuentra en una subrutina que es ejecutada con el comando GOSUB al inicio del programa, justo después de limpiar la pantalla. Para terminar de dar color al fondo de pantalla modifiqué el programa para asignar al fondo de pantalla el color cian y darle la apariencia de ser el cielo. También quité la asignación aleatoria de colores a la bola y la pala para que no coincidieran con los colores del fondo o la pista. A la bola le asigné el color rojo y a la pala el color marrón.

85 GOSUB 6000

140 POKE 53281,3

170 POKE 53287,2
180 POKE 53288,9

Con el fondo de pantalla la apariencia del juego mejora mucho. Unas gradas con público y unas nubes cruzando el cielo también le irían bien. En el siguiente artículo modifico el juego para utilizar bitmaps multicolor.

No hay comentarios:

Publicar un comentario