Programando un MANIC MINER - 1ª Parte

dancresp
Mensajes: 5334
Registrado: 13 Nov 2010 02:08
Agradecido : 148 veces
Agradecimiento recibido: 285 veces

Programando un MANIC MINER - 1ª Parte

Mensajepor dancresp » 06 Abr 2011 11:04


Programando un MANIC MINER
[ 1ª Parte ]


El objetivo de este tutorial consiste en aprender a programar una versión del juego MANIC MINER y descubrir distintas técnicas de programación para optimizar el código. He seleccionado este juego porque es un auténtico clásico, con pocas pantallas y gráficos. Esto nos permitirá generar un código muy compacto, ya que en los juegos, la mayor parte de la memoria se dedica a los gráficos y a los datos de las pantallas.

Quiero dejar claro que ignoro como se ha programado el juego original, y que lo que voy a hacer es reproducirlo según mis métodos de programación. Por otro lado, no vamos a programar el juego completo, pero lo que hagamos será totalmente funcional. El objetivo es explicar como se puede hacer, y el que quiera que lo complete o modifique a su gusto.

El programa está escrito en BASIC para MSX, pero las técnicas empleadas son completamente válidas para cualquier microordenador con unas características similares. Una vez el programa funcione, podremos empezar a reprogramar algunas partes del código en ensamblador para descubrir que el programa se ejecuta mucho más rápidamente y que la cantidad de memoria necesaria se reduce considerablemente.

Inicialmente, el tutorial se divide en 7 partes:

- Rutina de presentación de la pantalla de juego.
- Rutina de carga de los gráficos y colores.   
- Nudo principal de desarrollo.
- Rutinas de control de enemigos.
- Rutinas de control de Willy, el protagonista.
- Rutinas de control de marcadores, inicio y final de partida.
- Adaptación a código máquina de algunas rutinas del juego.

Y si alguien se quiere entretener a adaptar el código a otros sistemas, encantado. Lo he diseñado para que sea bastante simple.

Imagen


RUTINA DE PRESENTACIÓN DE LA PANTALLA DE JUEGO

Todos los elementos que configuran las distintas pantallas han sido codificados para conseguir que funcione con muy pocos datos. Con esto, conseguimos que ocupe poca memoria, se reduzca el tamaño del código y se ejecute más rápidamente.

Codificación de los datos:
A partir de la línea 9010 se han introducido los datos de la primera pantalla, en varias líneas DATA.

Formato de la codificación:
La rutina está preparada para poner un gráfico en una posición concreta de la pantalla, o una tira de ellos vertical o horizontalmente. Cada 4 o 5 valores representan un gráfico o una tira de ellos, según el siguiente formato:

1º- Acción a realizar: "1" Tira horizontal, "2" Tira vertical, "3" un único carácter y "255" fin datos de la pantalla.
2º- Posición inicial horizontal.
3º- Posición inicial vertical.
4º- Posición máxima en repeticiones. Si la acción es tipo "3" no hay que introducir este valor.
5º- Carácter a imprimir.

Por ejemplo:
La secuencia "2, 0, 0, 15, 1" indica que hay que poner una tira de caracteres tipo "1" (ladrillos) a partir de la posición 0,0 hasta la posición 0,15. Esto dibuja la pared de ladrillos de la izquierda.
La secuencia "3, 24, 4, 5" coloca la llave (carácter 5) que hay en el suelo, entre las dos plantas.

Los códigos de los gráficos tienen la siguiente relación:
1- Ladrillos.
2- Suelo.
3- Cinta transportadora.
4- Suelo que se deshace.
5- Llave.
6- Estalactita.
7- Planta.

En otras pantallas veremos como se añaden nuevos códigos.

En cada pantalla cambiaremos los gráficos, pero la función de cada uno de estos códigos será exactamente el mismo.

Funcionamiento de la rutina:
La rutina está ubicada a partir de la línea 6200.

Con el READ de la línea 6210 empezamos a leer los valores del DATA de la línea 9010. El primer valor lo ponemos en "D", que es el código de la acción que hemos de realizar.
Si la acción es "1" o "2",  leemos los siguientes 4 valores de DATA y los ponemos en las variables "H", "V", "R" y "G", y ejecutamos un bucle que repite la impresión hasta llegar a la posición indicada en "R".
Si la acción es "3", leemos los siguientes 3 valores de DATA y ponemos un único carácter en la posición indicada.
Si la acción es "255" damos por finalizada la impresión de la pantalla y salimos de esta rutina.

Así, la variable "D" contiene la acción, "V" la posición vertical, "H" la posición horizontal, "G" el gráfico elegido, y opcionalmente, en "R" la posición máxima cuando la acción es "1" o "2".

Por ahora, los códigos de los caracteres van del 1 al 7, pero en realidad no usamos estos, sino que en la línea 6240 lo pasamos al valor ASCII correcto. Se han seleccionado unos valores más simples para que sea más fácil recordarlos.

Como podéis ver, tanto el código de la rutina como de los datos es muy pequeño. Sólo 21 líneas.

Si ejecutamos el programa veremos que aparece la pantalla, pero en lugar de los gráficos aparecen distintos caracteres ASCII. Esto quiere decir que queda por redefinir el juego de caracteres con los gráficos del juego.

Vamos a ver como se hace.

Imagen


RUTINA DE CARGA DE LOS GRÁFICOS

En el MSX el juego de caracteres está almacenado en la ROM, pero al iniciar el sistema se vuelcan en la memoria de video VRAM, y allí es donde los tendremos que modificar.

Codificación de los gráficos:

A partir de la línea 9000 se han introducido los datos de los gráficos en líneas DATA.

Formato de la codificación:

La rutina está preparada para redefinir los caracteres indicados. Así, el primer valor del DATA indica el carácter a redefinir, y los siguientes 8 valores corresponden a los datos del gráfico, con un tamaño de 8x8 pixels.

Funcionamiento de la rutina:
La rutina está ubicada a partir de la línea 6000.

Mediante el RESTORE de la línea 6000 nos situaremos en la línea DATA que contiene los datos de los gráficos de la pantalla correspondiente.

Con el READ de la línea 6010 leemos el primer valor y lo ponemos en "D", que es el código del carácter a redefinir. Si este valor es "0", dejamos de redefinir más caracteres. En caso contrario, un bucle leer los siguientes 8 valores del DATA y los mete en la posición de memoria de la VRAM donde está almacenado ese carácter. El primer carácter está en la posición 0 de la VRAM. Con el cálculo de la línea 6025 sabremos a partir de que posición hemos de volcar los datos de ese carácter.

Si ejecutamos el programa, veremos que ya aparecen los gráficos en la pantalla pero en blanco sobre negro. Esto quiere decir que queda por redefinir los atributos de los caracteres del juego.

Un último esfuerzo y ya está.

Imagen


RUTINA DE CARGAS DE LOS COLORES

El modo SCREEN 1 del MSX es una pantalla de texto con posibilidad de usar SPRITES. En este modo la forma de trabajar con los colores es un poco peculiar. En otros sistemas, un byte en la memoria de video indica un carácter en una posición de pantalla, y otro byte indica el atributo de color de esa posición. En el MSX la cosa es más simple y limitada. Cada 8 caracteres consecutivos de la tabla ASCII  pueden tener un único atributo de color compartido. Así, "@ABCDEFG" han de tener el mismo color y la "HIJKLMNO" pueden tener otro distinto. De esta forma, con solo 32 bytes en la memoria de video controlamos los colores de los 256 caracteres. Una forma realmente original, pero poco práctica. Por un lado, al poner una letra en pantalla ya sale con el color asignado, cosa que hace que sea más rápido, pero por otro lado no te permite poner un texto en pantalla con distintos colores. Para ello deberíamos usar el modo SCREEN 2, que ya es totalmente gráfico, pero más complejo de gestionar.

Codificación de los colores:
A partir de la línea 9007 se han introducido los datos de los colores en una línea DATA.

Formato de la codificación:
Los colores se han almacenado en 10 valores. Se cambian los atributos de color desde el carácter 128 hasta el 207. En principio es más que suficiente para los pocos gráficos que hemos de usar.

Funcionamiento de la rutina:
La rutina está ubicada a partir de la línea 6100. Simplemente leemos los 10 valores de la línea DATA y vamos haciendo un VPOKE en la dirección de la VRAM correspondiente. Este valor se indica en la línea 6100.

Misión cumplida.

Imagen


NUDO PRINCIPAL


En la línea 100 comienza el nudo principal de desarrollo, que es el lugar desde donde iremos llamando al resto de rutinas.

Ahora mismo:
- Activa el modo SCREEN 1 haciendo un GOSUB 7000
- Carga los gráficos de la pantalla con un GOSUB 6000
- Queda en pausa hasta que se pulse una tecla, con el INKEY$ de la línea 300
- Activa el modo SCREEN 0 para volver al editor BASIC.

Estas líneas irán cambiando a lo largo del tutorial para ir recogiendo los sucesivos cambios que se produzcan.


RUTINA DE ACTIVACION DEL MODO GRAFICO


En la línea 7000 comienza una subrutina que desactiva la línea inferior del BASIC donde se muestran los valores de las teclas de función, activa el modo SCREEN 1, pone el ancho en 31 caracteres y configura los colores por defecto.


RUTINA DE ACTIVACION DEL MODO TEXTO

En la línea 7100 comienza  una subrutina que activa el modo SCREEN 0, vuelve a configurar los colores normales y activa la línea inferior del BASIC y nos devuelve al editor.


RESUMEN Y COMENTARIOS:

En las líneas DATA no es obligatorio seguir la numeración que he indicado. Lo único importante es que los datos estén introducidos con el formato y orden indicado: datos de los gráficos, datos de los atributos de color y datos de la pantalla de juego. Es recomendable no mezclar los valores en una misma línea para que sea más fácil una posterior identificación y modificación.

Algunos partes se podrían haber optimizado para ganar algo de velocidad, pero las he dejado como están para que sea más fácil  y comprensible por si alguien quiere adaptarlo a otro sistema.

El nudo principal de desarrollo lo he puesto en las primeras líneas, ya que en esta zona el BASIC es más rápido.

Toda la explicación de este tutorial la he realizado al revés de como funciona el programa, ya que como se puede apreciar en el listado, lo primero que se hace es redefinir los gráficos, asignar sus atributos de color e imprimir la pantalla. Esto se ha hecho así para comprender mejor las distintas etapas del proceso.


El listado de todo este montaje queda así.

Imagen


Para terminar, todo este desarrollo se ha realizado en un MSX-2 PHILIPS VG-8235 y el listado se ha impreso en una impresora matricial BROTHER M-1109. A lo retro, como dios manda.


Avatar de Usuario
ron
Mensajes: 18346
Registrado: 28 Oct 2010 14:20
Ubicación: retrocrypta
Agradecido : 1531 veces
Agradecimiento recibido: 1291 veces

Re: Programando un MANIC MINER - 1ª Parte

Mensajepor ron » 06 Abr 2011 18:25

Dancresp, cada vez te superas ! ! !

Muchas gracias, me ha gustado muchísimo. Ficha convenientemente subida a contenido.

Saludos

jepalza

Re: Programando un MANIC MINER - 1ª Parte

Mensajepor jepalza » 07 Abr 2011 09:55

dancresp escribió:
..... el listado se ha impreso en una impresora matricial BROTHER M-1109. A lo retro, como dios manda.



MUY bueno Imagen


dancresp
Mensajes: 5334
Registrado: 13 Nov 2010 02:08
Agradecido : 148 veces
Agradecimiento recibido: 285 veces

Re: Programando un MANIC MINER - 1ª Parte

Mensajepor dancresp » 14 Abr 2011 22:25

javu61, he respondido a tus observaciones aquí.

Un saludo  Imagen

javu61
Mensajes: 325
Registrado: 26 Mar 2011 15:58
Agradecimiento recibido: 1 vez

Re: Programando un MANIC MINER - 1ª Parte

Mensajepor javu61 » 15 Abr 2011 00:42

Hola:

Hay dos temas que hay que grabar a fuego a los programadores, y que por muchos años que pasen, sigo viendo en progrmas, usar comentarios por lo menos de bloques y no duplicar código, lo primero ayuda bastante a separar el programa y ver los bloques, buscar lo que quieres y arreglarlo, y mas en este casi que es didáctico, y lo segundo ahorra horas de depuración por errores tontos, y de voler a duplicar el código si hay que modificarlo, con el peligro de que se olvide en algún sitio.

Le mejor forma de que se vean los REM es poner guiones hasta completar la línea (sin pasarse de línea que entonces es peor)

100 REM Comienzo de la rutina de pantalla -------------------------------------------------------------------

Así la línea destaca siempre, o usar tres líneas

100 REM --------------------------------------------------
101 REM Comienzo de la rutina de pantalla
102 REM --------------------------------------------------

Esto se ve mejor, pero en ambos casos, si no va compilado, es desaprobechar memoria, bien normalmente escaso.

Por ser un programa didactico, entiendo que no optimices los data, pero si deberías añadir los comentarios.

De todas formas, eso no quita que esté bien explicado y sea bastante didáctico, en eso no puedo quitarte un ápice de mérito.

Imagen

Saludos

dancresp
Mensajes: 5334
Registrado: 13 Nov 2010 02:08
Agradecido : 148 veces
Agradecimiento recibido: 285 veces

Re: Programando un MANIC MINER - 1ª Parte

Mensajepor dancresp » 15 Abr 2011 09:23

Entono un "mea culpa" por el tema de quitar los REM.
En el listado definitivo me comprometo a trufarlo de comentarios. Ya avisaré que no es necesario copiarlos.

Te invito a repasar el segundo listado. Si hay algo que creas se puede mejorar, lo incorporaré en el listado definitivo.

Un saludo

afx
Mensajes: 603
Registrado: 25 Nov 2010 23:26
Agradecido : 14 veces
Agradecimiento recibido: 36 veces

Re: Programando un MANIC MINER - 1ª Parte

Mensajepor afx » 15 Abr 2011 10:32

Dancresp, este hilo está ¡genial! Tu tutorial es muy claro, detallado y didáctico.

Ánimo con esa serie de entregas.

dancresp
Mensajes: 5334
Registrado: 13 Nov 2010 02:08
Agradecido : 148 veces
Agradecimiento recibido: 285 veces

Re: Programando un MANIC MINER - 1ª Parte

Mensajepor dancresp » 15 Abr 2011 12:24

Gracias afx, se hace lo que se puede . Imagen
Hay un tema que quedará cojo: EL SONIDOImagen

¿Alguien se atreve?
¿javu61, como se te da el tema?

A las malas algo haré, pero si alguien lo hace bien... pues mejor.

Azimut

Re: Programando un MANIC MINER - 1ª Parte

Mensajepor Azimut » 01 May 2011 11:13

dancresp, me parece genial el tutorial que te estas currando.

Ya tengo ganas de ver la siguiente parte !guayx

Este tipo de tutoriales esta muy bien, ya que hay mucha gente que programo hace años y ahora tienen que refrescar sus ideas, o simplente les apetece iniciarse en un lenguaje facil de aprender.

!plax !plax !plax

Davidgs
Mensajes: 497
Registrado: 23 Mar 2011 20:27

Re: Programando un MANIC MINER - 1ª Parte

Mensajepor Davidgs » 01 May 2011 16:57

Dancresp, en dos palabras im-prezionante!!!
Enhorabuena, hasta yo que soy un inútil estoy aprendiendo mogollón. Tengo muchas ganas de ver como continua esto!!!

javu61
Mensajes: 325
Registrado: 26 Mar 2011 15:58
Agradecimiento recibido: 1 vez

Re: Programando un MANIC MINER - 1ª Parte

Mensajepor javu61 » 01 May 2011 20:48

dancresp escribió:¿javu61, como se te da el tema?


Pues no he tenido nunca MSX, aunque ahora tengo 3 y ya no hay escusas, lo investigaré un poco, pero se de programación, no de música, por lo que hay que buscar la sintonía original, seguro que está por algún lado.

Saludos

Avatar de Usuario
ron
Mensajes: 18346
Registrado: 28 Oct 2010 14:20
Ubicación: retrocrypta
Agradecido : 1531 veces
Agradecimiento recibido: 1291 veces

Re: Programando un MANIC MINER - 1ª Parte

Mensajepor ron » 01 May 2011 21:05

Empezaría buscando en los remakes de manic miner multiplataforma y seguramente entre los que tienen el código fuente ( que son varios ) estarán todas las musicas y sonidos y secuencias....

dancresp
Mensajes: 5334
Registrado: 13 Nov 2010 02:08
Agradecido : 148 veces
Agradecimiento recibido: 285 veces

Re: Programando un MANIC MINER - 1ª Parte

Mensajepor dancresp » 01 May 2011 22:33

Celebro que el tema interese. Anima a seguir haciendo cosas así.

Respecto a la segunda entrega, la subí hace unos cuantos días. Está aquí.

Y sobre la tercera y última, en menos de dos semanas la subo. Falta depurar el código para mejorar el rendimiento. Cosas del BASIC.

Un saludo


Volver a “Lenguajes de Programación y herramientas Dev”

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado