As usual, I remind you of the repository location for this game. You can get all the code and source from this location on GitHub.
Adding a SID file to the program source
Creating music and sound effects is an art I do not master, so it would've taken me a lot of time to create. I was really happy when I was offered assistance. Hedning from Genesis Project PMed me on CSDB and offered his assistance on getting me sounds for the game. Shortly thereafter I received a .SID file, made by Vanje Utne. You may know her from DeviantArt, and all kinds of demo's on the C64. Here is her page. Many thanks to both of you!!
A .SID file is a standardized way of distributing sound files, programs and definitions. Because of the standardization they can be used in players, emulators and on real Commodore 64's. The HSVC collection consists of only SID files, so in theory I could have taken any song in that library and use it for this game. But I chose to have at least one original bit in this remake :)
.var music = LoadSid("audio.sid")
.pc = music.location
.fill music.size, music.getData(i)
We get the music location from the object, point the assembler to that location, and then we write that data. NOW we can use the SID file from our program.
Usually, a raster IRQ is set up to run the music independently from the program. The IRQ is called once a frame, the play subroutine is called, and then the main program is continued. As we are already calling the game code once a frame (remember that the main loop is waiting for a specific raster position) we don't need to setup an interrupt to run the music. Let's not complicate things when we don't have to. In the main loop, we add this at the end:
// music definitions in sound file
.const SND_MOVE_BLOCK = 0
.const SND_ROTATE_BLOCK = 1
.const SND_DROP_BLOCK = 2
.const SND_LINE = 3
.const SND_TETRIS = 4
.const SND_PAUSE_ON = 5
.const SND_PAUSE_OFF = 6
.const SND_OPTION = 7
.const SND_MUSIC_TITLE = 9
.const SND_MUSIC_GAMEOVER = 8
// set accumulator before calling this
How to use this: Load the accumulator with any of the defined values, and call this subroutine. The main loop call to music.play will take care of the rest.
We start the music when a mode starts. For the title screen, the call...
Sound effects need to be played when something happens, but where to add the calls? After some playing around, I settled for the file play.asm. Here is an example: After using a control, the correct sound is played:
Above you see the first addition, but that file now plays sound for each action. Here is another example from the pause section of the same file. The correct sound is played for pausing or un-pausing the game:
lda pauseFlag // get the current pause flag
eor #000001 // flip between 0 and 1
sta pauseFlag // store it
cmp #$01 // pause mode?
beq !skip+ // yes
jmp RestorePlayArea // no, restore the screen
// game is paused. so clear the screen
lda #$01 // set the erase flag
sta playAreaErase // so area gets cleared as well
jsr SavePlayArea // save and clear the play area
Adding the sound and music isn't that hard, especially when you have someone with experience creating the sounds for you, haha!
There are still some small things that need fixing, like overlapping sound effects when hitting controls too fast, but overall I'm quite happy.
There is also something strange going on with timing when I use the joystick controls. This needs investigation, especially since I've moved my development system over to Linux Mint. I am running Linux Vice now and I need to be sure that the problem is not coming from changing Vice versions, or a configuration setting in the emulator...
We'll fix those things later on in another post. I wanted to get this post up because it has been a long time ago since the last part in the series.
So, until next time: happy coding, and check out the repository for the code changes and details.