Log In  


Cart #34878 | 2017-01-03 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
11

Demo Controls:
Position the pointer in one of the 4 quarters using the arrow keys to change the music.

The music will change depending on which quarter you're in. The check marks in these quarters show which channels are enabled for each quarter.

The changes will go into effect as soon as the pattern ended.

Background Story:
I came up with the idea of having the music chance depending on where you are while still keeping the same song. I quickly ran into an issue. I realized that there was no way to make this happen using just the "music" function.

Later that day I found out about the "peek" and "poke" functions: allowing you to directly read and write to ram. I found out where to find the music pattern section and started mapping it out to get more control over it.

Music in RAM:
Let's take a look at how the music patterns are mapped out in RAM:

Start: 0x3100:
64 patterns (256 byte).

pattern (4-byte):
0x0 [1-bit loopStart][1-bit active][6-bit soundIndex]
0x1 [1-bit loopEnd  ][1-bit active][6-bit soundIndex]
0x2 [1-bit advance  ][1-bit active][6-bit soundIndex]
0x3 [1-bit unused?  ][1-bit active][6-bit soundIndex]

As you can see each pattern takes up 4 bytes, 1 for each channel minus 1-bit per channel which is used to store whether or not this pattern is the start of a loop, the end of a loop or simply the end of a song.

Of course writing the code for this is a little tedious. This is where the music library comes in!
enableSalesManVoice()

The Music Library!
The music library is a small library that you can use to manipulate the flow of your music on runtime!

This means that you can for example dynamically chance your music based on where the player is or what the player is doing.

The music library only consists of 6 functions which can be used to manipulate the music patterns. Everything that you can do from within the editor can be done at runtime.

Features:

  • Enable and disable a pattern channel.
  • Change the sound that a pattern channel plays.
  • Full control over the way your music loops and when it stops just like with the 3 blue buttons in the editor.

Changes made to a pattern that is currently playing will only go into effect the next time it plays. This means that you can easily change out the patterns without having to worry about it changing abruptly.

-- Music Library by Oli414

-- returns the full byte that represents a channel including the pattern flag.
-- mainly for internal use.
function m_getchannelbyte(pattern,channel)
	return peek(12544+pattern*4+channel)
end

-- sets the full byte that represents a channel including the pattern flag.
-- mainly for internal use.
function m_setchannelbyte(pattern,channel,value)
	poke(12544+pattern*4+channel,value)
end

-- returns wether or not the channel is active.
function m_getchannelactive(pattern,channel)
	return band(m_getchannelbyte(pattern,channel),64)~=0
end

-- sets wether or not the channel is active.
function m_setchannelactive(pattern,channel,active)
	local val=m_getchannelbyte(pattern,channel)
	if active then
		val=band(val,191)
	else
		val=bor(val,64)
	end
	m_setchannelbyte(pattern,channel,val)
end

-- returns the pattern flags (loop and stop).
-- return bool:loopstart,bool:loopend,bool:advance
function m_getpatternflags(pattern)
	return band(m_getchannelbyte(pattern,0),128)~=0,band(m_getchannelbyte(pattern,1),128)~=0,band(m_getchannelbyte(pattern,2),128)~=0
end

-- sets the pattern flags (loop and stop).
-- params bool:loopstart,bool:loopend,bool:advance
function m_setpatternflags(pattern,loopstart,loopend,advance)
	local flags={}
	flags[0]=loopstart
	flags[1]=loopend
	flags[2]=advance
	for i=0,3 do
		local val=m_getchannelbyte(pattern,i)
		if flags[i] then
			val=bor(val,128)
		else
			val=band(val,127)
		end
		m_setchannelbyte(pattern,i,val)
	end
end

Feel free to use it in your own game!

In case you're wondering, the song is a sped up, edited version of a song I made a few years ago:
https://www.youtube.com/watch?v=W8ZKLQeQOSM

11



[Please log in to post a comment]