2019-01-06 15:48:00 +01:00

141 lines
3.2 KiB
GDScript

"""
MOD reader by Yui Kinomoto @arlez80
"""
"""
ファイルから読み込み
@param path File path
@return smf
"""
func read_file( path ):
var f = File.new( )
if not f.file_exists( path ):
print( "file %s is not found" % path )
breakpoint
f.open( path, f.READ )
var stream = StreamPeerBuffer.new( )
stream.set_data_array( f.get_buffer( f.get_len( ) ) )
stream.big_endian = true
f.close( )
return self._read( stream )
"""
配列から読み込み
@param data PoolByteArray
@return smf
"""
func read_data( data ):
var stream = StreamPeerBuffer.new( )
stream.set_data_array( data )
stream.big_endian = true
return self._read( stream )
"""
読み込み
@param stream
@return smf
"""
func _read( stream ):
var name = self._read_string( stream, 20 )
var samples = self._read_sample_informations( stream )
var song_length = stream.get_u8( )
var unknown_number = stream.get_u8( )
var song_positions = stream.get_partial_data( 128 )[1]
var max_song_position = 0
for sp in song_positions:
if max_song_position < sp:
max_song_position = sp
var magic = self._read_string( stream, 4 )
var channel_count = 4
match magic:
"6CHN":
channel_count = 6
"FLT8", "8CHN", "CD81", "OKTA":
channel_count = 8
"16CN":
channel_count = 16
"32CN":
channel_count = 32
_:
# print( "Unknown magic" )
# breakpoint
pass
var patterns = self._read_patterns( stream, max_song_position, channel_count )
self._read_sample_data( stream, samples )
return {
"name": name,
"song_length": song_length,
"unknown_number": unknown_number,
"song_positions": song_positions,
"magic": magic,
"patterns": patterns,
"samples": samples,
}
"""
サンプルのデータを読み込む
"""
func _read_sample_informations( stream ):
var samples = []
for i in range( 0, 31 ):
var sample = {}
sample.name = self._read_string( stream, 22 )
sample.length = stream.get_u16( ) * 2
sample.fine_tune = stream.get_u8( ) & 0x0F
if 0x08 < sample.fine_tune:
sample.fine_tune = 0x10 - sample.fine_tune
sample.volume = stream.get_u8( )
sample.loop_start = stream.get_u16( ) * 2
sample.loop_length = stream.get_u16( ) * 2
samples.append( sample )
return samples
"""
パターンを読み込む
"""
func _read_patterns( stream, max_position, channels ):
var patterns = []
for position in range( 0, max_position ):
var pattern = []
for i in range( 0, 64 ):
var line = []
for ch in range( 0, channels ):
var v1 = stream.get_u16( )
var v2 = stream.get_u16( )
var sample_number = ( ( v1 >> 8 ) & 0xF0 ) | ( ( v2 >> 12 ) & 0x0F )
var key_number = v1 & 0x0FFF
var effect_command = v2 & 0x0FFF
line.append({
"sample_number": sample_number,
"key_number": key_number,
"effect_command": effect_command,
})
pattern.append( line )
patterns.append( pattern )
"""
波形データ読み込む
"""
func _read_sample_data( stream, samples ):
for sample in samples:
sample.data = stream.get_partial_data( sample.length )[1]
"""
文字列の読み込み
@param stream Stream
@param size string size
@return string
"""
func _read_string( stream, size ):
return stream.get_partial_data( size )[1].get_string_from_ascii( )