nav collision
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
##
|
||||
## Godot Mod Player Plugin by arlez80 (Yui Kinomoto)
|
||||
##
|
||||
|
||||
@tool
|
||||
extends EditorPlugin
|
||||
|
||||
# Nothing to do, the main logic to expose this to the user
|
||||
# is done via `class_name` in `ModPlayer.gd`.
|
||||
|
||||
func _get_plugin_name():
|
||||
return "Godot Mod Player"
|
||||
@@ -0,0 +1 @@
|
||||
uid://bfmp165qm0qf
|
||||
@@ -0,0 +1,271 @@
|
||||
##
|
||||
## MOD parser by あるる(きのもと 結衣) @arlez80
|
||||
##
|
||||
## MIT License
|
||||
##
|
||||
|
||||
@warning_ignore_start("untyped_declaration")
|
||||
@warning_ignore_start("unsafe_method_access")
|
||||
@warning_ignore_start("unused_variable")
|
||||
|
||||
class_name Mod
|
||||
|
||||
const period_table:Array[int] = [
|
||||
1712,1616,1525,1440,1357,1281,1209,1141,1077,1017, 961, 907,
|
||||
856, 808, 762, 720, 678, 640, 604, 570, 538, 508, 480, 453,
|
||||
428, 404, 381, 360, 339, 320, 302, 285, 269, 254, 240, 226,
|
||||
214, 202, 190, 180, 170, 160, 151, 143, 135, 127, 120, 113,
|
||||
107, 101, 95, 90, 85, 80, 76, 71, 67, 64, 60, 57,
|
||||
]
|
||||
|
||||
enum ModFlags {
|
||||
LINEAR_FREQUENCY_TABLE = 1,
|
||||
}
|
||||
|
||||
enum ModWaveFormType {
|
||||
SINE_WAVEFORM = 0,
|
||||
SAW_WAVEFORM = 1,
|
||||
SQUARE_WAVEFORM = 2,
|
||||
RAMDOM_WAVEFORM = 3,
|
||||
REV_SAW_WAVEFORM = 4,
|
||||
}
|
||||
|
||||
enum ModLoopType {
|
||||
NO_LOOP = 0,
|
||||
FORWARD_LOOP = 1,
|
||||
PING_PONG_LOOP = 2,
|
||||
}
|
||||
|
||||
class ModData:
|
||||
var module_name:String
|
||||
var tracker_name:String
|
||||
var version:int
|
||||
var flags:int = 0
|
||||
|
||||
var song_length:int
|
||||
var unknown_number:int
|
||||
var channel_count:int
|
||||
var song_positions:PackedByteArray
|
||||
var magic:String
|
||||
var patterns:Array # ModPattern[][]
|
||||
var instruments:Array[ModInstrument]
|
||||
|
||||
var init_tick:int = 6
|
||||
var init_bpm:int = 125
|
||||
var restart_position:int = 0
|
||||
|
||||
class ModPatternNote:
|
||||
var key_number:int
|
||||
var note:int
|
||||
var instrument:int
|
||||
var volume:int = 0
|
||||
var effect_command:int
|
||||
var effect_param:int
|
||||
|
||||
class ModInstrument:
|
||||
var name:String
|
||||
var samples:Array[ModSample]
|
||||
var volume_envelope:ModEnvelope
|
||||
var panning_envelope:ModEnvelope
|
||||
var vibrato_type:ModWaveFormType = ModWaveFormType.SINE_WAVEFORM
|
||||
var vibrato_speed:int = -1
|
||||
var vibrato_depth:int = -1
|
||||
var vibrato_depth_shift:int = -1
|
||||
var volume_fadeout:int = -1
|
||||
|
||||
class ModSample:
|
||||
var data:PackedByteArray
|
||||
var name:String
|
||||
var length:int
|
||||
var loop_start:int
|
||||
var loop_length:int
|
||||
var volume:int
|
||||
var finetune:int
|
||||
var loop_type:int = ModLoopType.FORWARD_LOOP # set(ModLoopType)
|
||||
var bit:int = 8 # 8 or 16
|
||||
var panning:int = -1
|
||||
var relative_note:int = 0
|
||||
|
||||
class ModEnvelope:
|
||||
var points:Array[ModEnvelopePoint]
|
||||
var point_count:int
|
||||
var sustain_point:int
|
||||
var loop_start_point:int
|
||||
var loop_end_point:int
|
||||
|
||||
var enabled:bool
|
||||
var sustain_enabled:bool
|
||||
var loop_enabled:bool
|
||||
|
||||
func set_flag( f:int ):
|
||||
self.enabled = ( f & 1 ) != 0
|
||||
self.sustain_enabled = ( f & 2 ) != 0
|
||||
self.loop_enabled = ( f & 4 ) != 0
|
||||
|
||||
class ModEnvelopePoint:
|
||||
var frame:int
|
||||
var value:int
|
||||
|
||||
class ModParseResult:
|
||||
var error:int = OK
|
||||
var data:ModData = null
|
||||
|
||||
func _init():
|
||||
pass
|
||||
|
||||
## ファイルから読み込み
|
||||
## @param path ファイルパス
|
||||
## @return 読んだ Modファイルデータ
|
||||
func read_file( path:String ) -> ModParseResult:
|
||||
var result: = ModParseResult.new( )
|
||||
|
||||
var f: = FileAccess.open( path, FileAccess.READ )
|
||||
if f.get_error( ) != OK:
|
||||
result.error = f.get_error( )
|
||||
return result
|
||||
|
||||
var stream:StreamPeerBuffer = StreamPeerBuffer.new( )
|
||||
stream.set_data_array( f.get_buffer( f.get_length( ) ) )
|
||||
stream.big_endian = true
|
||||
|
||||
result.data = self._read( stream )
|
||||
return result
|
||||
|
||||
## 配列から読み込み
|
||||
## @param data データ
|
||||
## @return ModData
|
||||
func read_data( data:PackedByteArray ) -> ModParseResult:
|
||||
var stream:StreamPeerBuffer = StreamPeerBuffer.new( )
|
||||
stream.set_data_array( data )
|
||||
stream.big_endian = true
|
||||
|
||||
var result: = ModParseResult.new( )
|
||||
result.data = self._read( stream )
|
||||
return result
|
||||
|
||||
## ストリームから読み込み
|
||||
## @param stream ストリーム
|
||||
## @return 読んだ Modファイルデータ
|
||||
func _read( stream:StreamPeerBuffer ) -> ModData:
|
||||
var mod: = ModData.new( )
|
||||
mod.module_name = self._read_string( stream, 20 )
|
||||
mod.tracker_name = ""
|
||||
mod.instruments = self._read_instruments( stream )
|
||||
mod.song_length = stream.get_u8( )
|
||||
mod.unknown_number = stream.get_u8( )
|
||||
mod.song_positions = stream.get_partial_data( 128 )[1]
|
||||
var max_song_position:int = 0
|
||||
for sp in mod.song_positions:
|
||||
if max_song_position < sp:
|
||||
max_song_position = sp
|
||||
|
||||
mod.magic = self._read_string( stream, 4 )
|
||||
var channel_count:int = 4
|
||||
match mod.magic:
|
||||
"6CHN":
|
||||
channel_count = 6
|
||||
"FLT8", "8CHN", "CD81", "OKTA":
|
||||
channel_count = 8
|
||||
"16CN":
|
||||
channel_count = 16
|
||||
"32CN":
|
||||
channel_count = 32
|
||||
_:
|
||||
if mod.magic.substr( 2 ) == "CH":
|
||||
channel_count = int( mod.magic )
|
||||
# print( "Unknown magic" )
|
||||
# breakpoint
|
||||
pass
|
||||
mod.channel_count = channel_count
|
||||
|
||||
mod.patterns = self._read_patterns( stream, max_song_position + 1, channel_count )
|
||||
self._read_sample_data( stream, mod.instruments )
|
||||
|
||||
return mod
|
||||
|
||||
## 楽器データを読み込む
|
||||
## @param stream ストリーム
|
||||
## @return 楽器データ
|
||||
func _read_instruments( stream:StreamPeerBuffer ) -> Array[ModInstrument]:
|
||||
var instruments:Array[ModInstrument] = []
|
||||
|
||||
for i in range( 31 ):
|
||||
var sample: = ModSample.new( )
|
||||
sample.name = self._read_string( stream, 22 )
|
||||
sample.length = stream.get_u16( ) * 2
|
||||
var finetune:int = stream.get_u8( ) & 0x0F
|
||||
if 0x08 < finetune:
|
||||
finetune = finetune - 0x10
|
||||
sample.finetune = finetune * 16
|
||||
sample.volume = stream.get_u8( )
|
||||
sample.loop_start = stream.get_u16( ) * 2
|
||||
sample.loop_length = stream.get_u16( ) * 2
|
||||
if sample.loop_length < 8:
|
||||
sample.loop_type = ModLoopType.NO_LOOP
|
||||
else:
|
||||
sample.loop_type = ModLoopType.FORWARD_LOOP
|
||||
|
||||
var instrument: = ModInstrument.new( )
|
||||
instrument.name = sample.name
|
||||
instrument.samples = []
|
||||
for k in range( 96 ):
|
||||
instrument.samples.append( sample )
|
||||
instrument.volume_envelope = ModEnvelope.new( )
|
||||
instrument.volume_envelope.enabled = false
|
||||
instrument.panning_envelope = ModEnvelope.new( )
|
||||
instrument.panning_envelope.enabled = false
|
||||
|
||||
instruments.append( instrument )
|
||||
|
||||
return instruments
|
||||
|
||||
## パターンを読み込む
|
||||
## @param stream ストリームデータ
|
||||
## @param max_positions 最大パターン数
|
||||
## @param channels 最大チャンネル数
|
||||
## @return パターンデータ
|
||||
func _read_patterns( stream:StreamPeerBuffer, max_position:int, channels:int ) -> Array: # Array of Array of Array of ModPatternNote
|
||||
var patterns:Array = [] # Array of Array of Array of ModPatternNote
|
||||
|
||||
for position in ( max_position ):
|
||||
var pattern:Array = [] # Array of Array of ModPatternNote
|
||||
for i in range( 64 ):
|
||||
var line:Array[ModPatternNote] = []
|
||||
for ch in ( channels ):
|
||||
var v1:int = stream.get_u16( )
|
||||
var v2:int = stream.get_u16( )
|
||||
var mod_pattern_note: = ModPatternNote.new( )
|
||||
mod_pattern_note.instrument = ( ( v1 >> 8 ) & 0xF0 ) | ( ( v2 >> 12 ) & 0x0F )
|
||||
mod_pattern_note.key_number = v1 & 0x0FFF
|
||||
mod_pattern_note.effect_command = ( v2 >> 8 ) & 0x0F
|
||||
mod_pattern_note.effect_param = v2 & 0x0FF
|
||||
# TODO: 遅かったら二分探索にでもしませんか
|
||||
if 0 < mod_pattern_note.key_number:
|
||||
mod_pattern_note.note = 23
|
||||
for k in period_table:
|
||||
mod_pattern_note.note += 1
|
||||
if k <= mod_pattern_note.key_number:
|
||||
break
|
||||
else:
|
||||
mod_pattern_note.note = 0
|
||||
line.append( mod_pattern_note )
|
||||
pattern.append( line )
|
||||
patterns.append( pattern )
|
||||
|
||||
return patterns
|
||||
|
||||
## 楽器のデータに基づき、波形を読み込む
|
||||
## @param stream ストリーム
|
||||
## @param instruments 波形を読み込む楽器データリスト
|
||||
func _read_sample_data( stream:StreamPeerBuffer, instruments:Array[ModInstrument] ) -> void:
|
||||
for instrument in instruments:
|
||||
var sample:Mod.ModSample = instrument.samples[0]
|
||||
if 0 < sample.length:
|
||||
sample.data = stream.get_partial_data( sample.length )[1]
|
||||
|
||||
## 文字列の読み込み
|
||||
## @param stream ストリーム
|
||||
## @param size 文字列サイズ
|
||||
## @return 読み込んだ文字列を返す
|
||||
func _read_string( stream:StreamPeerBuffer, size:int ) -> String:
|
||||
return stream.get_partial_data( size )[1].get_string_from_ascii( )
|
||||
@@ -0,0 +1 @@
|
||||
uid://ii8p1hyx5nbe
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1 @@
|
||||
uid://djgd6mugw2s47
|
||||
@@ -0,0 +1,6 @@
|
||||
[gd_scene load_steps=2 format=3 uid="uid://x5sjwrimtdmi"]
|
||||
|
||||
[ext_resource type="Script" path="res://addons/modplayer/ModPlayer.gd" id="1"]
|
||||
|
||||
[node name="ModPlayer" type="Node"]
|
||||
script = ExtResource("1")
|
||||
@@ -0,0 +1,275 @@
|
||||
##
|
||||
## XM parser by あるる(きのもと 結衣) @arlez80
|
||||
##
|
||||
## This script required Mod.gd for declaring the data structures.
|
||||
##
|
||||
## MIT License
|
||||
##
|
||||
|
||||
@warning_ignore_start("untyped_declaration")
|
||||
@warning_ignore_start("unsafe_method_access")
|
||||
@warning_ignore_start("unused_variable")
|
||||
@warning_ignore_start("int_as_enum_without_cast")
|
||||
@warning_ignore_start("return_value_discarded")
|
||||
|
||||
class_name XM
|
||||
|
||||
enum XMNoteFlags {
|
||||
NOTE = 0x01,
|
||||
INSTRUMENT = 0x02,
|
||||
VOLUME = 0x04,
|
||||
EFFECT_COMMAND = 0x08,
|
||||
EFFECT_PARAM = 0x10,
|
||||
|
||||
FIRST_BYTE_AS_FLAGS = 0x80,
|
||||
}
|
||||
|
||||
## ファイルから読み込む
|
||||
## @param path ファイルパス
|
||||
## @return xm
|
||||
func read_file( path:String ) -> Mod.ModParseResult:
|
||||
var result: = Mod.ModParseResult.new( )
|
||||
|
||||
var f: = FileAccess.open( path, FileAccess.READ )
|
||||
if f.get_error( ) != OK:
|
||||
result.error = f.get_error( )
|
||||
return result
|
||||
|
||||
var stream:StreamPeerBuffer = StreamPeerBuffer.new( )
|
||||
stream.set_data_array( f.get_buffer( f.get_length( ) ) )
|
||||
|
||||
result.data = self._read( stream )
|
||||
if result.data == null:
|
||||
result.error = ERR_PARSE_ERROR
|
||||
return result
|
||||
|
||||
## 配列から読み込む
|
||||
## @param data データ
|
||||
## @return xm
|
||||
func read_data( data:PackedByteArray ) -> Mod.ModParseResult:
|
||||
var stream:StreamPeerBuffer = StreamPeerBuffer.new( )
|
||||
stream.set_data_array( data )
|
||||
|
||||
var result: = Mod.ModParseResult.new( )
|
||||
result.data = self._read( stream )
|
||||
if result.data == null:
|
||||
result.error = ERR_PARSE_ERROR
|
||||
return result
|
||||
|
||||
## ストリームから読み込み
|
||||
## @param stream ストリーム
|
||||
## @return xm
|
||||
func _read( stream:StreamPeerBuffer ) -> Mod.ModData:
|
||||
var xm: = Mod.ModData.new( )
|
||||
|
||||
if self._read_string( stream, 17 ) != "Extended Module: ":
|
||||
return null
|
||||
xm.module_name = self._read_string( stream, 20 )
|
||||
if stream.get_u8( ) != 0x1A:
|
||||
return null
|
||||
xm.tracker_name = self._read_string( stream, 20 )
|
||||
xm.version = stream.get_u16( )
|
||||
|
||||
var header_size:int = stream.get_u32( )
|
||||
xm.song_length = stream.get_u16( )
|
||||
xm.restart_position = stream.get_u16( )
|
||||
xm.channel_count = stream.get_u16( )
|
||||
|
||||
var pattern_count:int = stream.get_u16( )
|
||||
var instrument_count:int = stream.get_u16( )
|
||||
xm.flags = stream.get_u16( )
|
||||
xm.init_tick = stream.get_u16( )
|
||||
xm.init_bpm = stream.get_u16( )
|
||||
|
||||
xm.song_positions = stream.get_partial_data( header_size - 20 )[1]
|
||||
|
||||
xm.patterns = self._read_patterns( stream, xm.flags, pattern_count, xm.channel_count )
|
||||
if len( xm.patterns ) == 0:
|
||||
return null
|
||||
|
||||
xm.instruments = self._read_instruments( stream, instrument_count )
|
||||
if len( xm.instruments ) == 0:
|
||||
return null
|
||||
|
||||
return xm
|
||||
|
||||
## パターン読み込み
|
||||
## @param stream ストリーム
|
||||
## @param xm_file_flags XMデータに関するフラグ
|
||||
## @param pattern_count パターン数
|
||||
## @param channles 最大チャンネル数
|
||||
## @return パターンデータ
|
||||
func _read_patterns( stream:StreamPeerBuffer, xm_file_flags:int, pattern_count:int, channels:int ) -> Array: # Array of Array of Array of ModPatternNote
|
||||
var patterns:Array = [] # Array of Array of Array of ModPatternNote
|
||||
|
||||
for i in ( pattern_count ):
|
||||
var pattern:Array = [] # Array of Array of ModPatternNote
|
||||
|
||||
if stream.get_u32( ) != 9:
|
||||
return []
|
||||
if stream.get_u8( ) != 0:
|
||||
return []
|
||||
var row_count:int = stream.get_u16( )
|
||||
var size:int = stream.get_u16( )
|
||||
for k in ( row_count ):
|
||||
var line:Array[Mod.ModPatternNote] = []
|
||||
for ch in ( channels ):
|
||||
var patr: = Mod.ModPatternNote.new( )
|
||||
if 0 < size:
|
||||
var first:int = stream.get_u8( )
|
||||
size -= 1
|
||||
if first & XMNoteFlags.FIRST_BYTE_AS_FLAGS != 0:
|
||||
if first & XMNoteFlags.NOTE != 0:
|
||||
patr.note = stream.get_u8( )
|
||||
size -= 1
|
||||
else:
|
||||
patr.note = first
|
||||
first = 0xFF
|
||||
if 0 < patr.note:
|
||||
patr.note -= 1
|
||||
if first & XMNoteFlags.INSTRUMENT != 0:
|
||||
patr.instrument = stream.get_u8( )
|
||||
size -= 1
|
||||
if first & XMNoteFlags.VOLUME != 0:
|
||||
patr.volume = stream.get_u8( )
|
||||
size -= 1
|
||||
if first & XMNoteFlags.EFFECT_COMMAND != 0:
|
||||
patr.effect_command = stream.get_u8( )
|
||||
size -= 1
|
||||
if first & XMNoteFlags.EFFECT_PARAM != 0:
|
||||
patr.effect_param = stream.get_u8( )
|
||||
size -= 1
|
||||
if 0 < patr.note:
|
||||
if xm_file_flags & Mod.ModFlags.LINEAR_FREQUENCY_TABLE != 0:
|
||||
patr.key_number = self._conv_linear_freq( patr.note )
|
||||
else:
|
||||
patr.key_number = self._conv_amiga_freq( patr.note )
|
||||
line.append( patr )
|
||||
pattern.append( line )
|
||||
patterns.append( pattern )
|
||||
|
||||
return patterns
|
||||
|
||||
## ノート番号からAMIGA式で周波数計算する
|
||||
## @param note ノート番号
|
||||
## @return 周波数
|
||||
func _conv_amiga_freq( note:int ) -> int:
|
||||
return int( 6848.0 / pow( 2.0, note / 12.0 ) )
|
||||
|
||||
## ノート番号から線形で周波数計算する
|
||||
## @param note ノート番号
|
||||
## @return 周波数
|
||||
func _conv_linear_freq( note:int ) -> int:
|
||||
return 7680 - note * 64
|
||||
|
||||
## 楽器データを読み込む
|
||||
## @param stream ストリーム
|
||||
## @param instrument_count 楽器数
|
||||
## @return 楽器データ
|
||||
func _read_instruments( stream:StreamPeerBuffer, instrument_count:int ) -> Array[Mod.ModInstrument]:
|
||||
var instruments:Array[Mod.ModInstrument] = []
|
||||
|
||||
for i in ( instrument_count ):
|
||||
var inst: = Mod.ModInstrument.new( )
|
||||
var size:int = stream.get_u32( )
|
||||
var remain_size:int = size
|
||||
inst.name = self._read_string( stream, 22 )
|
||||
#print( "%d/%d %s" % [ i, instrument_count, inst.name] )
|
||||
var instrument_type:int = stream.get_u8( )
|
||||
if instrument_type != 0:
|
||||
# 0以外のやつもいるらしいので無視
|
||||
#return []
|
||||
pass
|
||||
|
||||
var sample_count:int = stream.get_u16( )
|
||||
var sample_numbers:Array = []
|
||||
remain_size -= 4 + 22 + 1 + 2
|
||||
if 0 < sample_count:
|
||||
var sample_header_size:int = stream.get_u32( )
|
||||
sample_numbers = stream.get_partial_data( 96 )[1]
|
||||
inst.volume_envelope = Mod.ModEnvelope.new( )
|
||||
for k in range( 12 ):
|
||||
var ve: = Mod.ModEnvelopePoint.new( )
|
||||
ve.frame = stream.get_u16( )
|
||||
ve.value = stream.get_u16( )
|
||||
inst.volume_envelope.points.append( ve )
|
||||
inst.panning_envelope = Mod.ModEnvelope.new( )
|
||||
for k in range( 12 ):
|
||||
var pe: = Mod.ModEnvelopePoint.new( )
|
||||
pe.frame = stream.get_u16( )
|
||||
pe.value = stream.get_u16( )
|
||||
inst.panning_envelope.points.append( pe )
|
||||
remain_size -= 4 + 96 + 48 + 48
|
||||
inst.volume_envelope.point_count = stream.get_u8( )
|
||||
inst.panning_envelope.point_count = stream.get_u8( )
|
||||
inst.volume_envelope.sustain_point = stream.get_u8( )
|
||||
inst.volume_envelope.loop_start_point = stream.get_u8( )
|
||||
inst.volume_envelope.loop_end_point = stream.get_u8( )
|
||||
inst.panning_envelope.sustain_point = stream.get_u8( )
|
||||
inst.panning_envelope.loop_start_point = stream.get_u8( )
|
||||
inst.panning_envelope.loop_end_point = stream.get_u8( )
|
||||
inst.volume_envelope.set_flag( stream.get_u8( ) )
|
||||
inst.panning_envelope.set_flag( stream.get_u8( ) )
|
||||
inst.vibrato_type = stream.get_u8( )
|
||||
inst.vibrato_speed = stream.get_u8( )
|
||||
inst.vibrato_depth = stream.get_u8( )
|
||||
inst.vibrato_depth_shift = stream.get_u8( )
|
||||
inst.volume_fadeout = stream.get_u16( )
|
||||
remain_size -= 16
|
||||
|
||||
if 0 < remain_size:
|
||||
stream.get_partial_data( remain_size ) # reserved
|
||||
|
||||
if 0 < sample_count:
|
||||
var sounds:Array[Mod.ModSample] = []
|
||||
# Sound Header
|
||||
for k in ( sample_count ):
|
||||
var xms: = Mod.ModSample.new( )
|
||||
xms.length = stream.get_u32( )
|
||||
xms.loop_start = stream.get_u32( )
|
||||
xms.loop_length = stream.get_u32( )
|
||||
xms.volume = stream.get_u8( )
|
||||
xms.finetune = stream.get_8( )
|
||||
xms.loop_type = stream.get_u8( )
|
||||
if xms.loop_type & 16 != 0:
|
||||
xms.bit = 16
|
||||
xms.loop_type &= 3
|
||||
xms.panning = stream.get_u8( )
|
||||
xms.relative_note = stream.get_8( )
|
||||
stream.get_u8( ) # Reserved
|
||||
xms.name = self._read_string( stream, 22 )
|
||||
sounds.append( xms )
|
||||
# Sound Data
|
||||
for xms in sounds:
|
||||
var d:Array[int] = []
|
||||
var p:int = 0
|
||||
|
||||
if xms.bit == 16:
|
||||
for k in ( xms.length >> 1 ):
|
||||
p += stream.get_16( )
|
||||
d.append( p & 0xFF )
|
||||
d.append( ( p >> 8 ) & 0xFF )
|
||||
else:
|
||||
for k in ( xms.length ):
|
||||
p += stream.get_8( )
|
||||
d.append( p & 0xFF )
|
||||
|
||||
xms.data = PackedByteArray( d )
|
||||
|
||||
inst.samples = []
|
||||
for k in sample_numbers:
|
||||
if len( sounds ) <= k:
|
||||
inst.samples.append( sounds[0] )
|
||||
else:
|
||||
inst.samples.append( sounds[k] )
|
||||
|
||||
instruments.append( inst )
|
||||
|
||||
return instruments
|
||||
|
||||
## 文字列の読み込み
|
||||
## @param stream ストリーム
|
||||
## @param size 文字列サイズ
|
||||
## @return 読み込んだ文字列を返す
|
||||
func _read_string( stream:StreamPeerBuffer, size:int ) -> String:
|
||||
return stream.get_partial_data( size )[1].get_string_from_ascii( )
|
||||
@@ -0,0 +1 @@
|
||||
uid://cmuxvykwoxljq
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 924 B |
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://ba4eaiuaq67p"
|
||||
path="res://.godot/imported/icon.png-1b6fd777bf08247b7c845db8b9125613.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://godot-mod-player-g4-master/addons/modplayer/icon.png"
|
||||
dest_files=["res://.godot/imported/icon.png-1b6fd777bf08247b7c845db8b9125613.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
@@ -0,0 +1,6 @@
|
||||
[plugin]
|
||||
name="Godot Mod Player"
|
||||
description="A plugin that playing Mod Files for Godot Engine."
|
||||
author="arlez80"
|
||||
version="4.3.0"
|
||||
script="GMP.gd"
|
||||
Reference in New Issue
Block a user