[ create a new paste ] login | about

Link: http://codepad.org/yYrNJFBn    [ raw code | fork ]

Lua, pasted on Mar 26:
--[[
    Necessary table-of-tables to tell Splisch which data in the ROM can be
        overwritten.  The workspace table has other implications as well
        (See documentation for more details)
--]]
workspace =
{
    ["maindata"] =    {["offset"] = 0x34782, ["size"] = 0x2B4D3, ["flags"] = "score,brr,clear"},
    ["score_ptr"] =   {["offset"] = 0x33D39, ["pitch"] = 3, ["size"] = 0xC0},
    ["brr_ptr"] =     {["offset"] = 0x33DF9, ["pitch"] = 3, ["size"] = 0x63},
    ["brr_loop"] =    {["offset"] = 0x33E5C, ["pitch"] = 2, ["size"] = 0x42},
    ["inst_freq"] =   {["offset"] = 0x33E9E, ["pitch"] = 2, ["size"] = 0x42},
    ["inst_adsr"] =   {["offset"] = 0x33EE0, ["pitch"] = 2, ["size"] = 0x42},
    ["inst_assign"] = {["offset"] = 0x33F22, ["pitch"] = 0x20, ["size"] = 0x800},
}

--[[
    Necessary functions to tell Splisch how many songs and instruments
        appear in this game
    You can hard-code values here, but I use calculations based
        on the above constants so that this is more dynamic
--]]

-- return the number of songs in this game
function desc_song_count()
    return math.min(
        workspace["score_ptr"].count,
        workspace["inst_assign"].count )
end

-- return the number of available instruments in this game
function desc_inst_count()
    return math.min(
        workspace["brr_ptr"].count,
        workspace["brr_loop"].count,
        workspace["inst_freq"].count,
        workspace["inst_adsr"].count )
end

-- return the number of instruments that are available for any 1 song
function desc_max_inst_per_song()
    return 0x10     -- this isn't very dynamic....
end

--[[
    Optional functions to tell Splisch other configuration details
--]]

function desc_score_max_size(song_id)   -- if omitted, defaults to nil (no maximum)
    return 0x1200
end

function desc_brr_max_size(song_id)     -- if omitted, defaults to nil (no maximum)
    return 0x7C0F
end

function desc_maindata_max_size(song_id)-- if omitted, defaults to nil (no maximum)
    return nil
end


--[[
    Necessary function called to load all the game-specific data.  This mostly
        involves loading instruments, but might also involve some other things that
        applies to every song in the game.
    Should call schload_set_inst_xxxx functions for each instrument available.
--]]

function desc_load_game()
    -- load up instrument pool
    for i=0, desc_inst_count()-1, 1 do
        -- get the pointer to the start of the brr data
        local start = workspace["brr_ptr"].read(i) + 2
        start = bit32.band(start,0x3FFFFF)
        
        -- and to the loop point for the brr data
        local loop = start + workspace["brr_loop"].read(i)
        
        -- give that to Splisch
        schload_set_instrument_brr_ptr(i, start, loop)
        
        -- instruments in this game also have an ADSR value associated with them
        schload_set_instrument_adsr(i,
            bit32.bor( 0x80, workspace["inst_adsr"].read(i,1,0) ),
            workspace["inst_adsr"].read(i,1,1)
            )
            
        -- AND, they also have pitch correction
        --   TODO -- do some kind of translation so this is more generic
        --    ie... define what this value actually is
        schload_set_instrument_pitch_adj( i, workspace["inst_freq"].read(i) )
    end
    
    -- Also, set the default echo and volume settings.
    -- These are probably configurable in the ROM somewhere, but I didn't find them.
    --   Not all of them are really "editable" fields anyway.
    schload_set_echo_length( 0x06 )
    schload_set_echo_feedback( 0x68 )
    schload_set_echo_fir( 0x7F,0,0,0,0,0,0,0 )
    
    schload_set_master_vol( 0x7F, 0x7F )
    schload_set_echo_vol( 0x20, 0x20 )
end

--[[
    Helper function to translate pointers for this game.
        Uses global glb_score_start and glb_score_bank
--]]
glb_score_start = 0
glb_score_bank = 0
function translate_score_ptr(ptr)
    ptr = ptr + glb_score_bank
    if ptr < glb_score_start then
        ptr = ptr + 0x10000
    end
    return ptr
end


--[[
    Necessary function called to load the details for a given song
--]]

function desc_load_song(song_id)
    -- The song has certain instruments assigned to it.  Assign those now
    for i=0, desc_max_inst_per_song()-1, 1 do
        schload_set_instrument_select( i, workspace["inst_assign"].read(song_id,2,i*2) )
    end
    
    
    -- Songs in this game have 8 channels.  Load them up by telling Splisch where the
    --   score data starts.
    glb_score_start = workspace["score_ptr"].read(song_id) + 2
    glb_score_start = bit32.band(glb_score_start,0x3FFFFF)
    glb_score_bank  = bit32.band(glb_score_start,0x3F0000)
    for i=0, 7, 1 do
        local ptr = sch_rom_read( glb_score_start + (i*2), 2 )
        
        schload_set_score_data_ptr( i, translate_score_ptr(ptr) )
    end
end

--[[
    These are called before/after to desc_load_score so that any 
    per channel initialization/destruction can take place.
    They are optional and can be omitted if you don't need them
--]]
function desc_load_channel_start( song_id, chan_id )
end
function desc_load_channel_end( song_id, chan_id )
end

--[[
    Processing score bytes!  This is called repeatedly for each 
    command in the score for this song.  The command byte(s) should be read
    through sch_rom_read, and the appropriate schload_score_xxx function should
    be called.
    
    Afterwards, the size in bytes of this command should be returned
--]]

-- global list to keep track of octaves
glb_octave = { [0]=0,0,0,0,0,0,0,0 }

-- global list for lengths -- note this should be editable!!!!!!
glb_lengths = { [0]=0xC0,0x90,0x60,0x40,0x48,0x30,0x20,0x24,0x18,0x10,0x0C,0x08,0x06,0x04,0x03 }

function desc_load_score( song_id, chan_id, offset )

    local op = sch_rom_read(offset)
    if op < 0xB4 then
        -- normal tone
        local tone = math.floor(op / 15) + glb_octave[chan_id]
        local len = op % 15
        schload_score_tone( tone, glb_lengths[len] )
        return 1
    elseif op < 0xC3 then
        -- sustain
        schload_score_sustain( op % 15 )
        return 1
    elseif op < 0xD2 then
        -- rest
        schload_score_rest( op % 15 )
        return 1
    elseif op == 0xD2 then
        schload_score_setvol(  sch_rom_read(offset+1)  )
        return 2
    elseif op == 0xD3 then
        schload_score_setvolfade(  sch_rom_read(offset+2), sch_rom_read(offset+1)  )
        return 3
    elseif op == 0xD4 then
        local pan = sch_rom_read(offset+1)
        if bit32.band(pan,0x80) then
            pan = -bit32.band(pand,0x7F)
        end
        schload_score_setpan(  pan / 0x7F  )
        return 2
    elseif op == 0xD5 then
        local pan = sch_rom_read(offset+2)
        if bit32.band(pan,0x80) then
            pan = -bit32.band(pand,0x7F)
        end
        schload_score_setpanfade(  sch_rom_read(offset+2), pan / 0x7F  )
        return 3
    elseif op == 0xD6 then      -- really don't know.  Tempo?
        schload_score_unknown(2)
        return 3
    elseif op == 0xD7 then      -- actually vibrato
        schload_score_unknown(3)
        return 4
    elseif op == 0xD8 then      -- actually vibrato stop
        schload_score_unknown()
        return 1
    elseif op == 0xD9 then      -- actually tremolo
        schload_score_unknown(3)
        return 4
    elseif op == 0xDA then      -- actually tremolo stop
        schload_score_unknown()
        return 1
    elseif op == 0xDB then      -- really don't know.
        schload_score_unknown(2)
        return 3
    elseif op == 0xDC then      -- really don't know.
        schload_score_unknown()
        return 1
    elseif op == 0xDD then
        schload_score_noisefreq( sch_rom_read(offset+1) )
        return 2
    elseif op == 0xDE then
        schload_score_enablenoise( true )
        return 1
    elseif op == 0xDF then
        schload_score_enablenoise( false )
        return 1
    elseif op == 0xE0 then
        schload_score_enablemod( true )
        return 1
    elseif op == 0xE1 then
        schload_score_enablemod( false )
        return 1
    elseif op == 0xE2 then
        schload_score_enableecho( true )
        return 1
    elseif op == 0xE3 then
        schload_score_enableecho( false )
        return 1
    elseif op == 0xE4 then
        glb_octave[chan_id] = sch_rom_read(offset+1)
        return 2
    elseif op == 0xE5 then
        glb_octave[chan_id] = glb_octave[chan_id] + 1
        return 1
    elseif op == 0xE6 then
        glb_octave[chan_id] = glb_octave[chan_id] - 1
        return 1
    elseif op == 0xE7 then      -- really set key change
        schload_score_unknown(1)
        return 2
    elseif op == 0xE8 then      -- really offset key change
        schload_score_unknown(1)
        return 2
    elseif op == 0xE9 then      -- really don't know
        schload_score_unknown(1)
        return 2
    elseif op == 0xEA then
        schload_score_setinst( sch_rom_read(offset+1) )
        return 2
    elseif op == 0xEB then      -- really set attack
        schload_score_unknown(1)
        return 2
    elseif op == 0xEC then      -- really set decay
        schload_score_unknown(1)
        return 2
    elseif op == 0xED then      -- really set sustain level
        schload_score_unknown(1)
        return 2
    elseif op == 0xEE then      -- really set sustain rate
        schload_score_unknown(1)
        return 2
    elseif op == 0xEF then      -- really set adsr back to inst defaults
        schload_score_unknown()
        return 1
    elseif op == 0xF0 then      -- really don't know
        schload_score_unknown(1)
        return 2
    elseif op == 0xF1 then      -- really don't know
        schload_score_unknown()
        return 1
    elseif op == 0xF2 then      -- really don't know (end song?)
        schload_score_unknown()
        return 1
    elseif op == 0xF3 then      -- really don't know
        schload_score_unknown(1)
        return 2
    elseif op == 0xF4 then      -- really don't know
        schload_score_unknown(2)
        return 3
    elseif op == 0xF5 then  -- nop
        return 2
    elseif op == 0xF6 then  -- nop
        return 3
    elseif op == 0xF7 then  -- nop
        return 3
    elseif op == 0xF8 then      -- really music master vol
        schload_score_unknown(1)
        return 2
    elseif op == 0xF9 then      -- really conditional jump (loop counter crap)
        schload_score_unknown(3)
        return 4
    elseif op == 0xFA then
        schload_score_jump( translate_score_ptr( sch_rom_read(offset+1,2) ) )
        return 3
    elseif op == 0xFB then      -- really conditional jump (1 time?)
        schload_score_unknown(2)
        return 3
    elseif op == 0xFC then      -- really zero's the loop counter
        schload_score_unknown()
        return 1
    elseif op == 0xFD then      -- really sets special instrument
        schload_score_unknown(1)
        return 2
    else        -- FE and FF ... end song?
        schload_score_unknown()
        return 1
    end
end


Create a new paste based on this one


Comments: