Hi all,
New here... just discovered this wonderful system yesterday... I still haven't experimented with actual game development on the platform, but did try the music tracker to check out its possibilities...
While dabbling around with a simple idea for a song with different parts, I assumed I could define each part as a self contained loop and then from the code just switch parts as appropiate. For example: play the first part twice, then the second part twice and then the third part once.
But when I went to search how that could be done I found no simple answer so I gave it a try and made two methods that both seem to work:
- Keep track of what pattern is playing and for how long and just when it's about to end use the music command to start playing the next part of the song. As the ticks received from the stat(56) change in jumps (the timing of music playing seems to be different than the one for the update function) you can't wait right unitl the end of the pattern, so I guess sometimes the jump might be noticeable. But the advantage is that you can switch to any other pattern freely...
- Keep track of what pattern is playing and dynamically change the loop start/end flags using the poke command to keep looping a part until you want to go to the next part. This has the advantage that the timing is perfect but you can't structure your song freely. You always either go back to the begining of the current part or let it run into the next one.
I put all the code into a function that initializes everything and retuns its own songupdate function to be called from _update, so it should be a matter of pasting it and defining the structure.
Right now the speed has to be manually entered and be the same for the whole song. I guess it'd be possible to get it from memory for each pattern...
Last, in the first method you have to set the loop flags on the tracker to define each section of the song, then define just the starting patterns for each section on the initial table. With the second method no loop flags should be set on the tracker and you define each section with the starting and ending pattern, adding a last section used to set the flags to go back to the begining of the song after it ends
Let me know if there're other ways of acomplishing this or any problems you might see...
To get the speed for each playing pattern:
function getspeed(p) adr=0x3100+p*0x4 sfx=@(adr) & 0000000000011111 return @(0x3200 + 68*sfx + 65) end |
It assumes the first track is active on the tracker...
Here's the whole code for case 1 (case 2 doesn't really need the speed):
function _init() -- define song structure -- each section has -- start pattern number -- times to play -- times played msections={{0,2,0},{2,2,0},{4,1,0}} initsong(msections) end function initsong(msections) local playing=1 function getspeed(p) adr=0x3100+p*0x4 sfx=@(adr) & 0000000000011111 return @(0x3200 + 68*sfx + 65) end function songupdate() local p=stat(54) local t=stat(56) -- check if this is the last -- pattern last=peek(0x3100+p*0x4+0x1)>=128 if last then if t>(getspeed(p)*32)-5 then msections[playing][3]+=1 end if msections[playing][3]==msections[playing][2] then msections[playing][3]=0 playing+=1 if playing>#msections then playing=1 end music(msections[playing][1]) end end end music(msections[playing][1]) end function _update() p=stat(54) t=stat(56) songupdate() end function _draw() cls() print("pat:"..p.." - t:"..t) end |
And the updated code for case 2:
function _init() cls() -- define song structure -- each section has -- start pattern number -- end pattern number -- times to play -- last section is the whole -- song, to go back to the -- start when finished msections={{0,1,2},{2,3,2},{4,5,1},{0,5,1}} songupdate=initmusic(msections,0) end function initmusic(msections) local playing=1 local times=0 local changed=false -- a should be true or false -- to set the flag or remove it function changeloop(s,a) adds=0x3100+msections[s][1]*0x4 adde=0x3100+(msections[s][2]*0x4)+0x1 vs=peek(adds) ve=peek(adde) if a then poke(adds,vs | 0b10000000) poke(adde,ve | 0b10000000) else poke(adds,vs & 0b1111111101111111.1111111111111111) poke(adde,ve & 0b1111111101111111.1111111111111111) end end function songupdate() local p=stat(54) last=p==msections[playing][2] if last then if not changed then times+=1 changed=true end if times==msections[playing][3] then times=0 changeloop(playing,false) playing+=1 if playing>#msections-1 then changeloop(playing,true) playing=1 changeloop(playing,true) else changeloop(playing,true) end end else changed=false end end -- init: changeloop(playing,true) music(msections[playing][0]) return songupdate end function _update() songupdate() end function _draw() cls() p=stat(54) t=stat(56) print("pat:"..p.." - t:"..t) end |
I've updated the carts too...
[Please log in to post a comment]