Menu principal

Para ir cerrando el mini curso, vamos a realizar un menú principal, en el que estará el nombre del juego, una leyenda que nos indique como comenzar a jugar (algo así como “Pulse F1 para comenzar”), y un efecto sencillo, para que no quede tan soso. Para muestra, mejor un vídeo:

Primero vamos a describir el efecto. Es simplemente un ciclado de colores del fondo de pantalla (se acuerdan? los primeros posts… ), pero les vamos a introducir un cutre delay, para que se engrosen las lineas. El efecto es medio azaroso, debido a que no hacemos ningún control del raster, pero así quedó mas o menos bonito ( eso si, pulsas una tecla y se desbanda completamente… esas cosas que tiene la simpleza 😛 ).
Ademas, la pantalla la dibujamos con caracteres invertidos, así tapamos todo, y lo que se muestra es el fondo que pasa a través de los caracteres invertidos…
Pfff, como explicación es pésima, mejor un ejemplo visual:

Caracteres invertidos jetpac_solo
Fondo ciclando anima_texto
Resultado final anima_texto_2

Para el código del ciclado de colores vamos a hacer lo siguiente:

main_menu:
{
          ldx            #0             
          stx            cborde
          ldx            #1             // establecemos colores de 
          stx            cfondo         // borde y fondo

          lda            #0      
          sta            spractive      // desactivamos todos los sprites
  
          ldx            #<menu_screen   // utilizamos la función
          stx            lsbCopyAddress     // que explicamos en el 
          ldx            #>menu_screen   // capitulo anterior y ... 
          stx            msbCopyAddress 
          jsr            copyToScreen       // copiamos pantalla

          ldx            #<menu_color
          stx            lsbCopyAddress
          ldx            #>menu_color
          stx            msbCopyAddress     
          jsr            copyToScreenColor  // idem para colores 

          // INICIO DEL EFECTO DE FONDO.
          ldy #0                  // inicializo indice tabla colores

loop:
          ldx            $CB       // leo ultima tecla pulsada
          cpx            #$04      // si pulso F1
          beq            go_main   // comienzo el juego

          lda            color_ramp,y   // tomamos el color de la 
                                        // tabla de colores que vamos 
                                        // a ciclar

loop_raster:
          ldx            raster    
r_line:   cpx            #$0         // posición de comparación (r_line + 1)
          bne            loop_raster
                                     // esto es mejorable... 
          inc            r_line+1    // incrementa posición de comparación
          inc            r_line+1    // esto lo que hace es engrosar la linea
          inc            r_line+1    // de fondo 
          inc            r_line+1    // es algo así como código automodificable
          inc            r_line+1    // si quitan algunos de estos inc
          inc            r_line+1    // se afina la linea
          inc            r_line+1    // si agregan se engrosa
          inc            r_line+1 
          inc            r_line+1 
          inc            r_line+1 
          inc            r_line+1 
          inc            r_line+1 
          sta            cfondo      // establezco el color de fondo    
          
          iny                        // tomo el próximo color de la rampa
          cpy            #7          
          bne            skip     
          ldy            #0          // y ciclo si llego al final de la rampa
          
skip:          
          jmp            loop     

go_main:
          jmp            start_game
}          
  
// colores que voy a ir ciclando en el fondo
color_ramp:
          .byte 7, 10, 8, 2, 9, 2, 8, 10

Ademas pueden ver que detectamos la pulsación de la tecla F1, eso se hace checkeando la posición de memoria $CB, que guarda la última tecla pulsada.

Quisiera detenerme en lo que me parece la parte mas confusa del código, que son las lineas inc r_line + 1. Lo que estamos haciendo aquí es modificar la posición de memoria ‘r_line + 1’, que corresponde a lo que en el código figura como ‘#$0’. Entonces, lo que hacemos es incrementar hasta el siguiente posición del raster, para luego cambiar al siguiente color. Si quito lineas ‘inc’, entonces la linea se afina, si agrego se engrosa…

Pueden descargar el proyecto desde el repositorio que se encuentra en https://github.com/moonorongo/jp_wars

y esto es todo por hoy, para la próxima entrega voy a tratar de poner algunos efectos de sonido (digo tratar, porque es un tema bastante difícil para mí… 😦 ). Hasta la próxima!

Actualización!!: A sugerencia del amigo @josepzin, del foro de Commodoremania, cambié la acción del menú principal para que, en vez de tener que pulsar F1 para comenzar, simplemente con disparar con cualquiera de los dos joysticks comience la acción. El código a continuación:

loop:
//          ldx            $CB       // CODIGO ANTERIOR:
//          cpx            #$04      // lo comenté a fin de 
//          beq            go_main   // mostrar el cambio realizado
          
          lda            joy1       // si pulso disparo 1
          and            #16           
          beq            go_main    // comienza el juego
          lda            joy2       // o disparo 2
          and            #16           
          beq            go_main    // también

Ahora si… 🙂

Anuncios

Migración a KickAssembler

Luego de un par de semanas inactivo sigo con el curso, pero previamente vamos a tener que introducir un pequeño (o no tanto) cambio. Por cuestiones ajenas a mi voluntad el sistema operativo de mi computadora reventó, así que decidí instalar LinuxMint. Lo que no pensé es que no iba a poder correr el CbmPrg Studio (solo corre en plataformas Windows), por lo que tuve que buscar otra opción, en lo posible multiplataforma.

Después de una larga investigación decidí optar por darle una oportunidad a KickAssembler, el cual es un crossassembler muy potente, escrito en java, por lo que se puede correr tanto en Windows, OSX, o Linux. El mismo posee un lenguaje de scripting muy similar a javascript, que te permite hacer autenticas maravillas, como por ejemplo importar un archivo .JPG, y convertirlo a una secuencia de bytes para mostrarlo en la pantalla de la C64.

Tuve que realizar algunas modificaciones al código (afortunadamente no fueron tantas), pero al final quedo mucho mejor. No tenemos la facilidades del IDE como por ejemplo hacer un click en un botón para ejecutar, pero si nos armamos un pequeño script que nos compile los archivos se nos facilita mucho la tarea.

Para que no se vuelvan locos, aquí voy a hacer una pequeña reseña de las modificaciones que realicé:

Main.asm

Como no tenemos un IDE que nos organice el proyecto todos los archivos que utilicemos los tenemos que importar en nuestro main.asm, lo cual es mas cómodo y claro (podemos ver como está con un simple editor de texto, sin depender de un programa especifico para una plataforma).

// BasicUpstart2: esta macro genera codigo en 
//  BASIC para iniciar el programa
BasicUpstart2(main)

/*
    JetPac Wars! Main File
*/

// Includes
#import "sprites.asm"
#import "vars.asm"
#import "macros.asm"

          *         = $1000 "Main Program"
main:
            jmp            main_menu

Aquí tenemos las primeras lineas de nuestro nuevo main.asm. La primera de todas muestra una funcionalidad de KickAsm, la cual genera el código BASIC para arrancar el juego, y toma como parámetro la etiqueta de inicio del código (noten que la etiqueta está inmediatamente luego * = $1000, o sea generará un SYS 4096).

Quienes tengan unos conocimientos de algún lenguaje ‘tipo C’ podrán apreciar que los comentarios se realizan de idéntica manera. Los archivos extras se incluyen con #import “archivo_a_importar.asm” en el orden en que los vamos importando (en el CbmPrg Studio teniamos que ir a las propiedades del projecto y cambiar el orden en una lista… aqui los tenemos todos a la vista).

Macros, labels, scoping y constantes

Las macros las invocamos como si fueran una función, ejemplo miSuperMacro(param1, param2, param3), y las definimos de la siguiente manera (lo podemos hacer en cualquier parte, no es necesario que sea antes de usarlas):

.macro unsetB8(spriteNumber) {
          lda            sprxBit8 
          and            #255 - spriteNumber
          sta            sprxBit8
}

Esta macro la invocamos simplemente con (por ejemplo) unsetB8(1).

Las etiquetas (labels) se definen con ‘nombre_etiqueta:’, y si le precedemos un signo ‘!’ podemos utilizar el mismo nombre dentro del ámbito en que se definen (Multi labels). Eso es util cuando tenemos una etiqueta tipo ‘next:’, en vez de andar poniendo ‘next1:’, ‘next2’, ‘next…’ simplemente las nombramos a todas con ‘!next:’ y las utilizamos como (por ej) ‘jmp !next+’ si quiero ir al siguiente ‘!next:’ o ‘jmp !next+’ si quiero ir al anterior . A continuación un ejemplo de código que muestra mas claramente lo que estoy explicando:

tickGenerator:
{
          ldx tick4
          dex
          stx tick4
          cpx #$ff
          bne !next+   // Salto al siguiente !next
          
          ldx #3
          stx tick4 
!next:
          ldx tick64
          dex
          stx tick64
          cpx #$ff
          bne !next+  // salto al !next siguiente 
          jmp !next-  // salto al !next previo
          ldx #64
          stx tick64 
!next:
          rts
}

Los lectores más observadores se habrán percatado de las llaves que encierran el código, como si fuera una función de c/java/php/etc … Estas llaves se utilizan para definir un ámbito (scope) de las etiquetas, así puedo darles el nombre que yo quiera, que no van a entrar en conflicto con nombres definidos en otros ámbitos.

Finalmente, el último cambio que tuve que introducir es la forma en que defino las constantes/punteros en ‘vars.asm’. Anteriormente se definían como ‘nombre = valor’, pero en KickAsm hay que hacerlo como ‘.const nombre = valor’.

Instalación y compilación

La instalación es muy sencilla, simplemente es un archivo comprimido que podemos descargar desde http://www.theweb.dk/KickAssembler/KickAssembler.zip, y lo descomprimimos en una carpeta que luego podamos recordar (ejemplo: c:/Archivos de Programa/KickAssembler).

Para compilar, simplemente escribiendo java -jar ‘c:/Archivos de Programa/KickAssembler/KickAss.jar’ main.asm hace toda la magia (lo mejor es armarse un archivo tipo ‘build.cmd’ que ejecutaremos cada vez que tengamos que compilar).

Nota: KickAssembler esta hecho en Java, por lo que necesitamos el runtime de Java instalado. Para descargarlo: https://java.com/en/download/.

Pueden descargar todas las modificaciones realizadas desde <a href=”https://github.com/moonorongo/jp_wars”>https://github.com/moonorongo/jp_wars</a&gt;

Ademas! Pueden descargar un release que armo la gente de Genesis Project, al que le hicieron un trainer y una intro muy linda: <a href=”http://csdb.dk/release/?id=157158″>Jetpac Wars Preview V3 +</a>

Y por hoy es todo, ahora si, en la próxima entrega voy a explicar como hice la pantalla de portada, y explicar el código de finalización de la partida. Hasta la proxima!