Efectos de sonido – parte 2

Con la teoría aprendida en el post anterior vamos a encarar el tema de los efectos sonoros. Vamos a realizar 2 sonidos: el disparo del jugador y la explosión al recibir el mismo.
Comenzaremos explicando el efecto de disparo, al ser de mayor complejidad de implementar. En primer lugar vamos a agregar las constantes de los registros del SID que vamos a utilizar (en vars.asm):

.const sidPtr    = 54272
.const sid_vol = 54296
.const sid_hfreq1 = 54273
.const sid_ad1 = 54277
.const sid_sr1 = 54278
.const sid_wave1 = 54276

Y luego vamos a inicializar los registros del SID en initvars.asm:

          
          ldy #0
          lda #0
loop:                     // reseteamos los registros
          sta sidPtr,y    
          iny 
          cpy #25
          bne loop

          // configuramos canal 1
          ldx #16          // volumen maximo 
          stx sid_vol
          ldx #0           // attack y decay en 0
          stx sid_ad1
          ldx #100
          stx sid_hfreq1   
          ldx #15*16+5     // volumen de sustain 15
          stx sid_sr1      // relax 5

Disparos

Para el sonido del disparo vamos a hacer un sonido que comenzará en una frecuencia alta, y en cada frame va disminuyendo la frecuencia hasta llegar a 0 (el típico sonido de disparos de naves). Para ello vamos a agregar un nuevo archivo que llamaremos sound_fire1.asm y lo importaremos desde main.asm inmediatamente después de importar animatePlayer1.asm.

Por que es importante esto? Bueno, porque vamos a utilizar la variable fire1 (que se pone en 1 cuando disparamos) y si colocamos el import luego de procesar el disparo nos vamos a encontrar que fire1 siempre esta en 0, ya que la parte que procesa el disparo lo pone en 0…

El código es muy simple: primero chequeamos que se haya producido un disparo, si es así ponemos el MSB de la frecuencia en 100, y comenzamos el sonido. Luego en cada frame vamos a ver si la frecuencia es distinta de 0, si es así decrementamos en 1, y cuando llega a 0 lo apagamos. El código, a continuación:

ldx fire1           
    cpx #1              // si se pulso disparo
    beq turn_on_fire1   // lo enciendo
    jmp dec_freq_1      // o sigo de largo
    
turn_on_fire1:    
    ldx #100             // inicializo la frecuencia
    stx sound_fire1_freq 
    ldx #17              // inicio el sonido
    stx sid_wave1        // con onda triangular
    
dec_freq_1:     
    ldx sound_fire1_freq 
    cpx #0               // comparo frec por 0
    beq turn_off_fire1   // si es igual lo apago
    
    stx sid_hfreq1       // y si no 
    dec sound_fire1_freq 
    dec sound_fire1_freq // lo decremento
    jmp exit
    
turn_off_fire1:    
    ldx #16
    stx sid_wave1
    
exit:

Explosiones

Este sonido es mucho mas simple, ya que solamente implica encenderlo y apagarlo. Vamos a usar el canal 3 del SID, con la siguiente configuración (en initvars.asm):

          // configuramos canal 3
          ldx #0
          stx sid_ad3    // attack/decay rapido
          ldx #3        
          stx sid_hfreq3 // frecuencia muy grave
          ldx #15*16+9   // volumen sustain max
          stx sid_sr3    // relax medio (9)

Poner relajación en 9 hace que cuando prendemos y apagamos el sonido va desvaneciéndose lentamente (mas alto el número, mas duración del sonido).
Luego, para simplificar y embellecer el código vamos a escribir una macro, a la que le pasaremos la frecuencia. De esta manera podremos utilizar diferentes sonidos de explosiones (ejemplo, si quisieramos una explosión diferente para cuando reventamos un tanque de combustible).

.macro playNoise(freq) {
    ldx #freq
    stx sid_hfreq3
    ldx #129
    stx sid_wave3
    ldx #128
    stx sid_wave3
}

Luego utilizaremos la macro donde detectamos que se produce una colisión (en detectCollision.asm) simplemente llamandola con playNoise(2)

Y esto es todo por hoy… y por el curso. Desde que inicié el tutorial a principio del año (con el efecto ciclado de colores) recorrimos un largo camino. Personalmente fue muy gratificante escribir este curso ya que me permitió aprender mucho mas de la C64/6502, además de mejorar como programador, redactor y educador.

A continuación, les dejo índice del curso. Además el enlace al proyecto en Github, mi página en Facebook, y mi Linkedin.

Índice del Curso

Proyecto en Github

Página personal en Facebook

Linked in

Más adelante tengo planeado hacer pequeños tutoriales acerca de programación de efectos, demos, gráficos y lo que se me ocurra sobre esta maravillosa maquina. Además quiero escribir un pequeño curso sobre como programar un motor gráfico para videojuegos en Javascript.

Nos vemos mas adelante!

Leave a Reply