mirror of
https://github.com/g012/l65.git
synced 2024-12-27 04:29:37 +00:00
Fixed ttt loader. Added vcs_music.l65 sample.
This commit is contained in:
parent
ce2737c353
commit
e5ead7c8f3
@ -101,6 +101,7 @@ Have a look at these files in the `samples` folder to get started with l65:
|
||||
* `vcs_banks.l65`: demonstrates 2 methods to call functions across banks.
|
||||
* `vcs_flush.l65`: a port of flewww's famous flush logo from the demo [.bin](http://www.pouet.net/prod.php?which=69666)
|
||||
* `vcs_spr48.l65`: a port of [.bin](http://www.pouet.net/prod.php?which=69666) title 48 pixels sprite animation.
|
||||
* `vcs_music.l65`: imports and plays back a TIATracker .ttt file directly.
|
||||
|
||||
There's also `vcspal.act`, a palette file for authoring software for VCS. Use this palette or a similar one to create 8b PNG for `l65.image` and helper loaders depending on it. You can generate such a palette, or a GPL one for GIMP using [vcsconv](https://github.com/g012/vcsconv) `authpalette` command.
|
||||
|
||||
@ -617,7 +618,6 @@ Note that the syntax file includes some highlighting for features only activated
|
||||
|
||||
* [k65](http://devkk.net/wiki/index.php?title=K65) style syntax
|
||||
* helpers to inter-operate with cc/ca65 and dasm
|
||||
* import TIATracker \*.ttt files directly
|
||||
|
||||
## Credits
|
||||
|
||||
|
12
l65.lua
12
l65.lua
@ -128,7 +128,7 @@ local opcode_absolute_x = lookupify{
|
||||
}
|
||||
local opcode_absolute_y = lookupify{
|
||||
'adc', 'and', 'cmp', 'eor', 'lda', 'ldx', 'ora', 'sbc',
|
||||
'sta', 'stx',
|
||||
'sta',
|
||||
-- illegal opcodes
|
||||
'dcp', 'isb', 'jam', 'las', 'lax', 'rla', 'rra', 'sax',
|
||||
'sha', 'shx', 'slo', 'shs', 'sre',
|
||||
@ -1618,6 +1618,7 @@ local function ParseLua(src, src_name)
|
||||
else
|
||||
tok:Commit()
|
||||
if not tok:ConsumeSymbol(',', tokenList) then
|
||||
if not opcode_absolute[op] and not opcode_zeropage[op] then return false, expr end
|
||||
suffix = suffix=='b' and "zpg" or suffix=='w' and "abs" or "zab"
|
||||
if suffix == 'zab' then
|
||||
if not opcode_zeropage[op] then suffix='abs'
|
||||
@ -1628,6 +1629,7 @@ local function ParseLua(src, src_name)
|
||||
stat = emit_call{name=op .. suffix, args={expr}, inverse_encapsulate=inverse_encapsulate} break
|
||||
end
|
||||
if tok:Peek().Data == 'x' then
|
||||
if not opcode_absolute_x[op] and not opcode_zeropage_x[op] then return false, expr end
|
||||
tok:Get(tokenList)
|
||||
local paren_close_whites = {}
|
||||
for _,v in ipairs(tokenList[#tokenList-1].LeadingWhite) do table.insert(paren_close_whites, v) end
|
||||
@ -1642,7 +1644,7 @@ local function ParseLua(src, src_name)
|
||||
stat = emit_call{name=op .. suffix, args={expr}, inverse_encapsulate=inverse_encapsulate, paren_open_white=paren_open_whites, paren_close_white=paren_close_whites} break
|
||||
end
|
||||
if tok:Peek().Data == 'y' then
|
||||
if not opcode_absolute_y[op] then return false, expr end
|
||||
if not opcode_absolute_y[op] and not opcode_zeropage_y[op] then return false, expr end
|
||||
tok:Get(tokenList)
|
||||
local paren_close_whites = {}
|
||||
for _,v in ipairs(tokenList[#tokenList-1].LeadingWhite) do table.insert(paren_close_whites, v) end
|
||||
@ -1660,6 +1662,7 @@ local function ParseLua(src, src_name)
|
||||
local mod_st, mod_expr = ParseExpr(scope)
|
||||
if not mod_st then return false, mod_expr end
|
||||
if not tok:ConsumeSymbol(',', tokenList) then
|
||||
if not opcode_absolute[op] and not opcode_zeropage[op] then return false, expr end
|
||||
suffix = suffix=='b' and "zpg" or suffix=='w' and "abs" or "zab"
|
||||
if suffix == 'zab' then
|
||||
if not opcode_zeropage[op] then suffix='abs'
|
||||
@ -1670,6 +1673,7 @@ local function ParseLua(src, src_name)
|
||||
stat = emit_call{name=op .. suffix, args={expr, mod_expr}, inverse_encapsulate=inverse_encapsulate} break
|
||||
end
|
||||
if tok:Peek().Data == 'x' then
|
||||
if not opcode_absolute_x[op] and not opcode_zeropage_x[op] then return false, expr end
|
||||
tok:Get(tokenList)
|
||||
local paren_close_whites = {}
|
||||
for _,v in ipairs(tokenList[#tokenList-1].LeadingWhite) do table.insert(paren_close_whites, v) end
|
||||
@ -1684,7 +1688,7 @@ local function ParseLua(src, src_name)
|
||||
stat = emit_call{name=op .. suffix, args={expr, mod_expr}, inverse_encapsulate=inverse_encapsulate, paren_open_white=paren_open_whites, paren_close_white=paren_close_whites} break
|
||||
end
|
||||
if tok:Peek().Data == 'y' then
|
||||
if not opcode_absolute_y[op] then return false, expr end
|
||||
if not opcode_absolute_y[op] and not opcode_zeropage_y[op] then return false, expr end
|
||||
tok:Get(tokenList)
|
||||
local paren_close_whites = {}
|
||||
for _,v in ipairs(tokenList[#tokenList-1].LeadingWhite) do table.insert(paren_close_whites, v) end
|
||||
@ -2546,7 +2550,7 @@ l65_def = {
|
||||
if not l65 then l65 = l65_def else for k,v in pairs(l65_def) do l65[k]=v end end
|
||||
l65.report = function(success, ...)
|
||||
if success then return success,... end
|
||||
local message=... io.stderr:write(message..'\n')
|
||||
local message=... io.stderr:write(tostring(message)..'\n')
|
||||
os.exit(-1)
|
||||
end
|
||||
l65.msghandler = function(msg)
|
||||
|
@ -449,9 +449,9 @@
|
||||
"waveform": 16
|
||||
}
|
||||
],
|
||||
"metaAuthor": "glafouk",
|
||||
"metaComment": "",
|
||||
"metaName": "ishtar",
|
||||
"metaAuthor": "Glafouk",
|
||||
"metaComment": "Crunchy tune taken from\n\nFlush VCS Music Cart Vol.1\n\nhttps://www.pouet.net/prod.php?which=71561\n\nBig up to Exocet,Flewww,g012 & p0ke for making this crazy project alive...\nAnd special danke to Kylearan for his marvelous TIAtracker !",
|
||||
"metaName": "Ishtar",
|
||||
"oddspeed": 6,
|
||||
"patterns": [
|
||||
{
|
||||
|
310
samples/vcs_music.l65
Normal file
310
samples/vcs_music.l65
Normal file
@ -0,0 +1,310 @@
|
||||
require'vcs'
|
||||
mappers['2K']()
|
||||
|
||||
local AUDC0s = 0x90
|
||||
local AUDC1s, AUDF0s, AUDF1s, AUDV0s, AUDV1s = AUDC0s+1, AUDC0s+2, AUDC0s+3, AUDC0s+4, AUDC0s+5
|
||||
local vubars = 0xA0
|
||||
local tmp = 0xF0
|
||||
|
||||
local zic_filename = 'Ishtar.ttt'
|
||||
local zic = ttt(zic_filename)
|
||||
print(string.format('Using file %s (ttt version %d)\n Name: %s\n Author: %s\n%s', zic_filename, zic.version, zic.name, zic.author, zic.comment))
|
||||
|
||||
-- debug printing of zic data
|
||||
--[[
|
||||
local printbytetable = function(v)
|
||||
local s = ' '
|
||||
for kk,vv in ipairs(v) do
|
||||
s = s .. string.format('%02x, ', vv)
|
||||
if #s >= 34 then print(s) s = ' ' end
|
||||
end
|
||||
if #s > 0 then print(s) end
|
||||
end
|
||||
for k,v in pairs(zic) do
|
||||
if type(v) ~= 'table' then
|
||||
print(k,v)
|
||||
elseif type(v[1]) == 'number' then
|
||||
print(k) printbytetable(v)
|
||||
elseif type(v[1]) == 'table' then
|
||||
for ek, e in ipairs(v) do
|
||||
print(k, ek, e.name) printbytetable(e)
|
||||
end
|
||||
end
|
||||
end
|
||||
]]
|
||||
|
||||
@@tt_InsCtrlTable byte(zic.insctrltable)
|
||||
@@tt_InsADIndexes byte(zic.insadindexes)
|
||||
@@tt_InsSustainIndexes byte(zic.inssustainindexes)
|
||||
@@tt_InsReleaseIndexes byte(zic.insreleaseindexes)
|
||||
@@tt_InsFreqVolTable byte(zic.insfreqvoltable)
|
||||
@@tt_PercIndexes byte(zic.percindexes)
|
||||
@@tt_PercFreqTable byte(zic.percfreqtable)
|
||||
@@tt_PercCtrlVolTable byte(zic.percctrlvoltable)
|
||||
local patterns = {}
|
||||
for i,pattern in ipairs(zic.patterns) do
|
||||
table.insert(patterns, section("pattern"..i)) byte(pattern)
|
||||
end
|
||||
@@tt_PatternSpeeds byte(zic.patternspeeds)
|
||||
@@tt_PatternPtrLo byte_lo(patterns)
|
||||
@@tt_PatternPtrHi byte_hi(patterns)
|
||||
@@tt_SequenceTable byte(zic.sequence[1]) byte(zic.sequence[2])
|
||||
|
||||
local tt = {
|
||||
-- =====================================================================
|
||||
-- Permanent variables. These are states needed by the player.
|
||||
-- =====================================================================
|
||||
'timer', -- current music timer value
|
||||
'cur_pat_index_c0', -- current pattern index into tt_SequenceTable
|
||||
'cur_pat_index_c1',
|
||||
'cur_note_index_c0', -- note index into current pattern
|
||||
'cur_note_index_c1',
|
||||
'envelope_index_c0', -- index into ADSR envelope
|
||||
'envelope_index_c1',
|
||||
'cur_ins_c0', -- current instrument
|
||||
'cur_ins_c1',
|
||||
-- =====================================================================
|
||||
-- Temporary variables. These will be overwritten during a call to the
|
||||
-- player routine, but can be used between calls for other things.
|
||||
-- =====================================================================
|
||||
'ptr', -- 2 bytes
|
||||
}
|
||||
for k,v in ipairs(tt) do tt[v] = k + 0x7F end
|
||||
|
||||
tt.FREQ_MASK = 0b00011111
|
||||
tt.INS_HOLD = 8
|
||||
tt.INS_PAUSE = 16
|
||||
tt.FIRST_PERC = 17
|
||||
|
||||
tt.fetchCurrentNoteImpl = function()
|
||||
@_constructPatPtr
|
||||
ldy tt.cur_pat_index_c0,x lda tt_SequenceTable,y
|
||||
if zic.usegoto then
|
||||
bpl _noPatternGoto
|
||||
;and #0b01111111 sta tt.cur_pat_index_c0,x bpl _constructPatPtr
|
||||
@_noPatternGoto
|
||||
end
|
||||
tay lda tt_PatternPtrLo,y sta tt.ptr lda tt_PatternPtrHi,y sta tt.ptr+1
|
||||
if zic.overlay then
|
||||
clv
|
||||
lda tt.cur_note_index_c0,x bpl _notPrefetched
|
||||
;and #0b01111111 sta tt.cur_note_index_c0,x
|
||||
bit tt_Bit6Set
|
||||
@_notPrefetched
|
||||
tay
|
||||
else
|
||||
ldy tt.cur_note_index_c0,x
|
||||
end
|
||||
lda (tt.ptr),y bne _noEndOfPattern
|
||||
sta tt.cur_note_index_c0,x
|
||||
inc tt.cur_pat_index_c0,x
|
||||
bne _constructPatPtr
|
||||
@_noEndOfPattern
|
||||
end
|
||||
if zic.useoverlay then
|
||||
@@tt_fetchCurrentNoteSection tt.fetchCurrentNoteImpl() rts
|
||||
tt.fetchCurrentNote = function() jsr tt_fetchCurrentNoteSection end
|
||||
else
|
||||
tt.fetchCurrentNote = tt.fetchCurrentNoteImpl
|
||||
end
|
||||
|
||||
@@tt_CalcInsIndex
|
||||
lsr lsr lsr lsr lsr
|
||||
tay
|
||||
@tt_Bit6Set
|
||||
rts
|
||||
|
||||
local function zic_tick()
|
||||
dec tt.timer bpl _noNewNote
|
||||
ldx #1
|
||||
@_advanceLoop
|
||||
tt.fetchCurrentNote()
|
||||
cmp #tt.INS_PAUSE
|
||||
if zic.useslide then
|
||||
beq _pause
|
||||
bcs _newNote
|
||||
adc tt.cur_ins_c0,x sec sbc #8 sta tt.cur_ins_c0,x
|
||||
bcs _finishedNewNote
|
||||
else
|
||||
bcc _finishedNewNote
|
||||
bne _newNote
|
||||
end
|
||||
@_pause
|
||||
lda tt.cur_ins_c0,x jsr tt_CalcInsIndex
|
||||
lda tt_InsReleaseIndexes-1,y
|
||||
clc adc #1 bcc _storeADIndex
|
||||
@_newNote
|
||||
sta tt.cur_ins_c0,x
|
||||
cmp #tt.FREQ_MASK+1 bcs _startInstrument
|
||||
tay
|
||||
lda tt_PercIndexes-tt.FIRST_PERC,y
|
||||
bne _storeADIndex
|
||||
@_startInstrument
|
||||
if zic.useoverlay then
|
||||
bvs _finishedNewNote
|
||||
end
|
||||
jsr tt_CalcInsIndex
|
||||
lda tt_InsADIndexes-1,y
|
||||
@_storeADIndex
|
||||
sta tt.envelope_index_c0,x
|
||||
@_finishedNewNote
|
||||
inc tt.cur_note_index_c0,x
|
||||
@_sequencerNextChannel
|
||||
dex
|
||||
bpl _advanceLoop
|
||||
if zic.globalspeed then
|
||||
ldx #zic.speed-1
|
||||
if zic.usefunktempo then
|
||||
lda tt.cur_note_index_c0 lsr bcc _noOddFrame ldx #zic.oddspeed-1 @_noOddFrame
|
||||
end
|
||||
stx tt.timer
|
||||
else
|
||||
ldx tt.cur_pat_index_c0 ldy tt_SequenceTable,x
|
||||
if zic.usefunktempo then
|
||||
lda tt.cur_note_index_c0 lsr
|
||||
lda tt_PatternSpeeds,y
|
||||
bcc _evenFrame
|
||||
;and #0x0f
|
||||
bcs _storeFunkTempo
|
||||
@_evenFrame
|
||||
lsr lsr lsr lsr
|
||||
@_storeFunkTempo
|
||||
sta tt.timer
|
||||
else
|
||||
lda tt_PatternSpeeds,y sta tt.timer
|
||||
end
|
||||
end
|
||||
@_noNewNote
|
||||
ldx #1
|
||||
@_updateLoop
|
||||
lda tt.cur_ins_c0,x
|
||||
if not zic.startswithnotes then
|
||||
beq _afterAudioUpdate
|
||||
end
|
||||
cmp #tt.FREQ_MASK+1 bcs _instrument
|
||||
ldy tt.envelope_index_c0,x
|
||||
lda tt_PercCtrlVolTable-1,y beq _endOfPercussion inc tt.envelope_index_c0,x @_endOfPercussion
|
||||
sta AUDV0,x lsr lsr lsr lsr sta AUDC0,x
|
||||
lda tt_PercFreqTable-1,y
|
||||
sta AUDF0,x
|
||||
sta AUDF0s,x -- EXTRA for vumeter rendering
|
||||
if zic.useoverlay then
|
||||
bpl _afterAudioUpdate
|
||||
tt.fetchCurrentNote()
|
||||
cmp #tt.FREQ_MASK+1
|
||||
bcc _afterAudioUpdate
|
||||
sta tt.cur_ins_c0,x
|
||||
jsr tt_CalcInsIndex
|
||||
lda tt_InsSustainIndexes-1,y sta tt.envelope_index_c0,x
|
||||
asl tt.cur_note_index_c0,x sec ror tt.cur_note_index_c0,x
|
||||
bmi _afterAudioUpdate
|
||||
else
|
||||
jmp _afterAudioUpdate
|
||||
end
|
||||
@_instrument
|
||||
jsr tt_CalcInsIndex
|
||||
lda tt_InsCtrlTable-1,y sta AUDC0,x
|
||||
sta AUDC0s,x -- EXTRA for vumeter rendering
|
||||
lda tt.envelope_index_c0,x cmp tt_InsReleaseIndexes-1,y bne _noEndOfSustain lda tt_InsSustainIndexes-1,y @_noEndOfSustain
|
||||
tay
|
||||
lda tt_InsFreqVolTable,y beq _endOfEnvelope iny @_endOfEnvelope
|
||||
sty tt.envelope_index_c0,x
|
||||
sta AUDV0,x
|
||||
sta AUDV0s,x -- EXTRA for vumeter rendering
|
||||
lsr lsr lsr lsr clc adc tt.cur_ins_c0,x sec sbc #8
|
||||
sta AUDF0,x
|
||||
sta AUDF0s,x -- EXTRA for vumeter rendering
|
||||
@_afterAudioUpdate
|
||||
dex
|
||||
bpl _updateLoop
|
||||
end
|
||||
|
||||
local function zic_init()
|
||||
if zic.c0init ~= 0 then lda#zic.c0init sta tt.cur_pat_index_c0 end
|
||||
if zic.c1init ~= 0 then lda#zic.c1init sta tt.cur_pat_index_c1 end
|
||||
end
|
||||
|
||||
|
||||
----------------------------------------------------------------------
|
||||
-- equalizer anim
|
||||
----------------------------------------------------------------------
|
||||
|
||||
-- convert to freq: http://atariage.com/forums/topic/257526-musicsound-programming-question-atari-2600/
|
||||
-- maps AUDCi to 0-7 3 bits (<<5) value for wave length of: 1, 2, 6, 15, 31, 93, 465, 511
|
||||
@@wavlen samepage
|
||||
dc.b 0x00,0x60,0xC0,0xC0,0x20,0x20,0x80,0x80,
|
||||
0xF0,0x80,0x80,0x00,0x40,0x40,0xA0,0xA0
|
||||
end
|
||||
local wavelen_map = { 1, 2, 6, 15, 31, 93, 465, 511 }
|
||||
local freq_ranges = { 30, 60, 120, 240, 480, 960, 1920, 9999999 }
|
||||
local t = {}
|
||||
for i=0,255 do
|
||||
local wavelen = wavelen_map[(i>>5)+1]
|
||||
local note = (i&31)+1
|
||||
local freq = 3546894 / 114 / wavelen / note
|
||||
for x=1,9 do
|
||||
if freq <= freq_ranges[x] then
|
||||
t[#t+1] = x-1
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
section{'regfreq', align=256} byte(t)
|
||||
@@vm_pf2 samepage
|
||||
dc.b 0x00,0x80,0xC0,0xE0,0xF0,0xF8,0xFC,0xFE,
|
||||
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
|
||||
end
|
||||
@@vm_pf1 samepage
|
||||
dc.b 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x01,0x03,0x07,0x0F,0x1F,0x3F,0x7F
|
||||
end
|
||||
@@vm_col samepage
|
||||
dc.b 0x3C,0x7C,0x9C,0xDC,0x2C,0x4C,0x6C,0xAC
|
||||
end
|
||||
local vumeter_tick = function()
|
||||
lda #0 ldy #15 @_vudec ldx vubars,y dex bmi _vudecskip stx vubars,y @_vudecskip dey bpl _vudec
|
||||
lda AUDF0s ldy AUDC0s ora wavlen,y tax ldy regfreq,x
|
||||
lda AUDV0s cmp vubars,y bmi _vuless0 sta vubars,y @_vuless0
|
||||
lda AUDF1s ldy AUDC1s ora wavlen,y tax ldy regfreq,x
|
||||
lda AUDV1s cmp vubars+8,y bmi _vuless1 sta vubars+8,y @_vuless1
|
||||
end
|
||||
local vumeter_draw = function()
|
||||
lda #ctrlpf.PF_MIRRORED sta CTRLPF
|
||||
ldy #7
|
||||
@_vudraw
|
||||
samepage
|
||||
lda #21 sta tmp
|
||||
@_vudraw1
|
||||
sta WSYNC
|
||||
lda vm_col,y sta COLUPF sleep(4)
|
||||
ldx vubars,y
|
||||
lda vm_pf1,x sta PF1
|
||||
lda vm_pf2,x sta PF2
|
||||
sleep(8)
|
||||
ldx vubars+8,y
|
||||
lda vm_pf2,x sta PF2
|
||||
lda vm_pf1,x sta PF1
|
||||
dec tmp bpl _vudraw1
|
||||
sta WSYNC lda #0 sta PF2 sta PF1
|
||||
sta WSYNC
|
||||
dey bpl _vudraw
|
||||
end
|
||||
lda #0 sta CTRLPF
|
||||
sta WSYNC sta WSYNC
|
||||
end
|
||||
|
||||
local tick = function()
|
||||
zic_tick()
|
||||
vumeter_tick()
|
||||
end
|
||||
|
||||
@@main
|
||||
init()
|
||||
zic_init()
|
||||
@_frame
|
||||
overscan() vblank(tick) screen(vumeter_draw) jmp _frame
|
||||
|
||||
; -- needed if last instruction is implied
|
||||
writebin(filename..'.bin')
|
||||
writesym(filename..'.sym')
|
||||
print(stats)
|
45
vcs.l65
45
vcs.l65
@ -468,19 +468,17 @@ ttt = function(filename)
|
||||
t.author = s.metaAuthor
|
||||
t.name = s.metaName
|
||||
t.comment = s.metaComment
|
||||
t.globalspeed = (s.globalspeed ~= nil and s.globalspeed or true) and 1 or 0
|
||||
t.speed = s.evenspeed - 1
|
||||
t.oddspeed = s.oddspeed - 1
|
||||
local usefunktempo
|
||||
if t.globalspeed == 1 then usefunktempo = s.evenspeed ~= s.oddspeed
|
||||
t.globalspeed = s.globalspeed == nil or s.globalspeed
|
||||
t.speed = s.evenspeed
|
||||
t.oddspeed = s.oddspeed
|
||||
if t.globalspeed then t.usefunktempo = s.evenspeed ~= s.oddspeed
|
||||
else
|
||||
for k,v in ipairs(s.channels[1].sequence) do
|
||||
local pattern = s.patterns[v.patternindex+1]
|
||||
if pattern.evenspeed ~= pattern.oddspeed then usefunktempo=true break end
|
||||
if pattern.evenspeed ~= pattern.oddspeed then t.usefunktempo=true break end
|
||||
end
|
||||
end
|
||||
t.usefunktempo = usefunktempo and 1 or 0
|
||||
t.usegoto,t.useslide,t.useoverlay,t.startswithnotes = 0,0,0,1
|
||||
t.usegoto,t.useslide,t.useoverlay,t.startswithnotes = false,false,false,true
|
||||
|
||||
local patternmap = {}
|
||||
local instrumentmap,instrumentcount = {},0
|
||||
@ -499,20 +497,22 @@ ttt = function(filename)
|
||||
local patternindex = sequence.patternindex + 1
|
||||
if not patternmap[patternindex] then
|
||||
patternmap[patternindex] = #t.patterns
|
||||
local pattern = { name = s.patterns[patternindex].name }
|
||||
local spattern = s.patterns[patternindex]
|
||||
local pattern = { name = spattern.name }
|
||||
ins(t.patterns, pattern)
|
||||
for noteindex,note in ipairs(s.patterns[patternindex].notes) do
|
||||
if note.type == 0 then -- Instrument
|
||||
for noteindex,note in ipairs(spattern.notes) do
|
||||
if note.type == 1 then -- Instrument
|
||||
if not instrumentmap[note.number] then
|
||||
instrumentmap[note.number] = instrumentcount
|
||||
local instrument = s.instruments[note.number+1]
|
||||
instrumentcount = instrumentcount + (instrument.waveform == 16 and 2 or 1)
|
||||
local sz = instrument.envelopeLength
|
||||
while sz > instrument.releaseStart+1 and instrument.frequencies[sz] == 0 and instrument.volumes[sz] == 0 do sz = sz-1 end
|
||||
local oldsz = #t.insfreqvoltable
|
||||
for i=1,sz do
|
||||
ins(t.insfreqvoltable, instrument.frequencies[i]+8 << 4 | instrument.volumes[i])
|
||||
end
|
||||
ins(t.insfreqvoltable, instrument.releaseStart+1, 0)
|
||||
ins(t.insfreqvoltable, instrument.releaseStart + 1 + oldsz, 0)
|
||||
ins(t.insfreqvoltable, 0)
|
||||
for i = 1, instrument.waveform == 16 and 2 or 1 do
|
||||
ins(t.insadindexes, insEnvelopeIndex)
|
||||
@ -530,7 +530,7 @@ ttt = function(filename)
|
||||
local valueIns = instrumentmap[note.number] + 1
|
||||
if s.instruments[note.number+1].waveform == 16 and note.value > 31 then valueIns=valueIns+1 end
|
||||
ins(pattern, valueIns<<5 | note.value&0x1f)
|
||||
elseif note.type == 1 then -- Percussion
|
||||
elseif note.type == 3 then -- Percussion
|
||||
if not percussionmap[note.number] then
|
||||
percussionmap[note.number] = percussioncount
|
||||
percussioncount = percussioncount + 1
|
||||
@ -547,30 +547,30 @@ ttt = function(filename)
|
||||
ins(t.percctrlvoltable, 0)
|
||||
ins(t.percindexes, percEnvelopeIndex+1)
|
||||
percEnvelopeIndex = percEnvelopeIndex + sz + 1
|
||||
if percussion.overlay then t.useoverlay = 1 end
|
||||
if percussion.overlay then t.useoverlay = true end
|
||||
end
|
||||
ins(pattern, percussionmap[note.number] + 17) -- NoteFirstPerc
|
||||
elseif note.type == 2 then -- Hold
|
||||
elseif note.type == 0 then -- Hold
|
||||
ins(pattern, 8) -- NoteHold
|
||||
if sequenceindex == 1 and noteindex == 1 then t.startswithnotes = 0 end
|
||||
elseif note.type == 3 then -- Pause
|
||||
if sequenceindex == 1 and noteindex == 1 then t.startswithnotes = false end
|
||||
elseif note.type == 2 then -- Pause
|
||||
ins(pattern, 16) -- NotePause
|
||||
elseif note.type == 4 then -- Slide
|
||||
ins(pattern, 8 + note.value) -- NoteHold + note.value
|
||||
t.useslide = 1
|
||||
t.useslide = true
|
||||
end
|
||||
end
|
||||
ins(pattern, 0)
|
||||
if t.globalspeed == 0 then
|
||||
ins(t.patternspeeds, usefunktempo and (t.speed << 4 | t.oddspeed) or t.speed)
|
||||
if not t.globalspeed then
|
||||
ins(t.patternspeeds, t.usefunktempo and (spattern.evenspeed-1 << 4 | spattern.oddspeed-1) or spattern.evenspeed-1)
|
||||
end
|
||||
end
|
||||
ins(t.sequence[channelindex], patternmap[patternindex])
|
||||
if sequence.gototarget ~= -1 then
|
||||
t.usegoto = 1
|
||||
t.usegoto = true
|
||||
local value = 128 + sequence.gototarget + gotooffset
|
||||
gotooffset = gotooffset + 1
|
||||
if channelindex == 1 then value = value + #channel.sequence[1] end
|
||||
if channelindex == 2 then value = value + #t.sequence[1] end
|
||||
assert(value < 256, "goto target in channel " .. (channelindex-1) .. " is out of range: " .. value)
|
||||
ins(t.sequence[channelindex], value)
|
||||
end
|
||||
@ -588,6 +588,7 @@ ttt = function(filename)
|
||||
if t.sequence[2][i+1] > 127 then t.c1init = t.c1init + 1 end
|
||||
i = i+1
|
||||
end
|
||||
t.c1init = t.c1init + #t.sequence[1]
|
||||
|
||||
return t
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user