78 lines
1.8 KiB
Lua
78 lines
1.8 KiB
Lua
track=klass()
|
|
function track:init()
|
|
self.frames={}
|
|
self.ix_to_frame={}
|
|
self.next_frame_start=0
|
|
end
|
|
function track:add(len)
|
|
for i=0,len-1 do
|
|
self.ix_to_frame[self.next_frame_start+i]={#self.frames,i}
|
|
end
|
|
add(self.frames,{
|
|
pattern:new({len=len}),
|
|
pattern:new({len=len}),
|
|
pattern:new({len=len}),
|
|
pattern:new({len=len}),
|
|
})
|
|
self.next_frame_start+=len
|
|
end
|
|
|
|
function track:pattern(channel,offset)
|
|
offset = offset or -1
|
|
channel &= 0xffff
|
|
offset &= 0xffff
|
|
|
|
assert_range(channel,0,4,"channel")
|
|
local n_frames_long=#self.frames
|
|
assert_range(offset,-n_frames_long,n_frames_long,"offset")
|
|
if offset<0 then
|
|
offset+=n_frames_long
|
|
end
|
|
return self.frames[offset+1][channel+1]
|
|
end
|
|
|
|
function track:plot(channel,offset,ndata)
|
|
assert_range(channel,0,4,"channel")
|
|
assert_range(offset,0,self.next_frame_start,"offset")
|
|
local tup=self.ix_to_frame[offset]
|
|
assert(tup) -- should be unable to fail
|
|
local frame,offset=unpack(tup)
|
|
self.frames[frame+1][channel+1]:plot(offset,ndata)
|
|
end
|
|
|
|
function track:build(
|
|
free_patterns,
|
|
frame_a,
|
|
frame_z
|
|
)
|
|
local n_frames_long = #self.frames
|
|
if (not frame_z) frame_z = frame_a + n_frames_long
|
|
assert(frame_z-frame_a == n_frames_long,
|
|
"wrong number of frames (must be "..
|
|
frame_a.." to "..frame_a+n_frames_long..")")
|
|
|
|
-- dump patterns and frames
|
|
local mapped_patterns={}
|
|
local function map_to_real_pattern(pat)
|
|
if (pat:silent()) return 0 | (1<<6)
|
|
|
|
local key = pat:key()
|
|
mapped_patterns[key] = mapped_patterns[key] or {}
|
|
local t = mapped_patterns[key]
|
|
for other in all(t) do
|
|
if (pat:eq(other)) return other.map_ix
|
|
end
|
|
assert(#free_patterns>0, "out of free patterns")
|
|
pat:map_to(deli(free_patterns,1))
|
|
add(t,pat)
|
|
return pat.map_ix
|
|
end
|
|
|
|
local fmaddr=0x3100+(frame_a)*4
|
|
for frame=1,n_frames_long do
|
|
for i=0,3 do
|
|
poke(fmaddr+i,map_to_real_pattern(self.frames[frame][i+1]))
|
|
end
|
|
fmaddr+=4
|
|
end
|
|
end |