mirror of
https://github.com/Relintai/gdfxr.git
synced 2025-04-24 05:43:23 +02:00
Compare commits
6 Commits
Author | SHA1 | Date | |
---|---|---|---|
d1e4b34cdc | |||
|
7b3194f500 | ||
|
4562f4b77c | ||
|
576708bb4a | ||
|
5b910afb64 | ||
|
9acce6be58 |
30
CHANGELOG.md
30
CHANGELOG.md
@ -6,8 +6,32 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [2.0.0] - 2023-02-23
|
||||
## [1.3.0] - 2023-02-23
|
||||
### Added
|
||||
- First release for Godot 4. See the `master` branch for Godot 3 support.
|
||||
- Bit depth and sample rate import options.
|
||||
- Paste from JSXFR.
|
||||
- Add default filename for Save As dialog, with trailing number incremented.
|
||||
|
||||
[2.0.0]: https://github.com/timothyqiu/gdfxr/releases/tag/2.0
|
||||
## [1.2.0] - 2022-10-13
|
||||
### Added
|
||||
- Implement custom slider.
|
||||
|
||||
## [1.1.1] - 2022-07-30
|
||||
### Fixed
|
||||
- Slider min value for a bipolar parameter should be -1.
|
||||
|
||||
## [1.1.0] - 2022-03-10
|
||||
### Added
|
||||
- Extra options menu: Save As, Copy, and Paste.
|
||||
- Add a copy of the LICENSE in the plugin folder.
|
||||
- Keep several recently generated sounds in the menu.
|
||||
|
||||
## [1.0.0] - 2022-02-25
|
||||
### Added
|
||||
- Initial release.
|
||||
|
||||
[1.0.0]: https://github.com/timothyqiu/gdfxr/releases/tag/1.0
|
||||
[1.1.0]: https://github.com/timothyqiu/gdfxr/releases/tag/1.1
|
||||
[1.1.1]: https://github.com/timothyqiu/gdfxr/releases/tag/1.1.1
|
||||
[1.2.0]: https://github.com/timothyqiu/gdfxr/releases/tag/1.2
|
||||
[1.3.0]: https://github.com/timothyqiu/gdfxr/releases/tag/1.3
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
你可以在 Godot 中把 sfxr 音效文件当作普通的音频文件使用,也可以像在原始的 sfxr 中一样对音效进行编辑。
|
||||
|
||||
> 🚧 如果你想在 Godot 3 里使用这个插件,请移步 [master](https://github.com/timothyqiu/gdfxr/tree/master) 分支。
|
||||
> 🚧 如果你想在 Godot 4 里使用这个插件,请移步 [godot-4](https://github.com/timothyqiu/gdfxr/tree/godot-4) 分支。
|
||||
|
||||
## 安装
|
||||
|
||||
|
@ -12,7 +12,7 @@ the popular program of choice to make retro sound effects for games.
|
||||
You can use sfxr sound files like regular audio files in Godot and edit sound files like in the
|
||||
original sfxr.
|
||||
|
||||
> 🚧 Checkout the [master](https://github.com/timothyqiu/gdfxr/tree/master) branch if you want to use this plugin in Godot 3.
|
||||
> 🚧 Checkout the [godot-4](https://github.com/timothyqiu/gdfxr/tree/godot-4) branch if you want to use this plugin in Godot 4.
|
||||
|
||||
## Installation
|
||||
|
||||
|
@ -11,7 +11,7 @@ static func b58decode(v: String) -> StreamPeerBuffer:
|
||||
v = v.lstrip(BASE_58_ALPHABET[0])
|
||||
var zeros := original_length - v.length()
|
||||
|
||||
var buffer := PackedByteArray()
|
||||
var buffer := PoolByteArray()
|
||||
buffer.resize(v.length()) # Won't be as long as base 58 string since the buffer is 256-based.
|
||||
buffer.fill(0)
|
||||
|
||||
@ -32,7 +32,7 @@ static func b58decode(v: String) -> StreamPeerBuffer:
|
||||
var result := StreamPeerBuffer.new()
|
||||
for _i in zeros:
|
||||
result.put_8(0)
|
||||
result.put_data(buffer.slice(buffer.size() - length))
|
||||
result.put_data(buffer.subarray(buffer.size() - length, -1))
|
||||
result.seek(0)
|
||||
|
||||
return result
|
||||
|
@ -55,9 +55,10 @@ var sound_vol := 0.5
|
||||
|
||||
|
||||
func load(path: String) -> int: # Error
|
||||
var f := FileAccess.open(path, FileAccess.READ)
|
||||
if not f:
|
||||
return FileAccess.get_open_error()
|
||||
var f := File.new()
|
||||
var err := f.open(path, File.READ)
|
||||
if err != OK:
|
||||
return err
|
||||
|
||||
var version := f.get_32()
|
||||
if not [100, 101, 102].has(version):
|
||||
@ -105,9 +106,10 @@ func load(path: String) -> int: # Error
|
||||
|
||||
|
||||
func save(path: String) -> int: # Error
|
||||
var f := FileAccess.open(path, FileAccess.WRITE)
|
||||
if not f:
|
||||
return FileAccess.get_open_error()
|
||||
var f := File.new()
|
||||
var err := f.open(path, File.WRITE)
|
||||
if err != OK:
|
||||
return err
|
||||
|
||||
f.store_32(102)
|
||||
f.store_32(wave_type)
|
||||
@ -152,88 +154,88 @@ func randomize_in_category(category: int) -> void:
|
||||
|
||||
match category:
|
||||
Category.PICKUP_COIN:
|
||||
p_base_freq = randf_range(0.4, 0.9)
|
||||
p_base_freq = rand_range(0.4, 0.9)
|
||||
p_env_attack = 0.0
|
||||
p_env_sustain = randf_range(0.0, 0.1)
|
||||
p_env_decay = randf_range(0.1, 0.5)
|
||||
p_env_punch = randf_range(0.3, 0.6)
|
||||
p_env_sustain = rand_range(0.0, 0.1)
|
||||
p_env_decay = rand_range(0.1, 0.5)
|
||||
p_env_punch = rand_range(0.3, 0.6)
|
||||
if randi() % 2:
|
||||
p_arp_speed = randf_range(0.5, 0.7)
|
||||
p_arp_mod = randf_range(0.2, 0.6)
|
||||
p_arp_speed = rand_range(0.5, 0.7)
|
||||
p_arp_mod = rand_range(0.2, 0.6)
|
||||
|
||||
Category.LASER_SHOOT:
|
||||
wave_type = randi() % 3
|
||||
if wave_type == 2 and randi() % 2:
|
||||
wave_type = randi() % 2
|
||||
p_base_freq = randf_range(0.5, 1.0)
|
||||
p_freq_limit = max(0.2, p_base_freq - randf_range(0.2, 0.8))
|
||||
p_freq_ramp = randf_range(-0.35, -0.15)
|
||||
p_base_freq = rand_range(0.5, 1.0)
|
||||
p_freq_limit = max(0.2, p_base_freq - rand_range(0.2, 0.8))
|
||||
p_freq_ramp = rand_range(-0.35, -0.15)
|
||||
if randi() % 3 == 0:
|
||||
p_base_freq = randf_range(0.3, 0.9)
|
||||
p_freq_limit = randf_range(0, 0.1)
|
||||
p_freq_ramp = randf_range(-0.65, -0.35)
|
||||
p_base_freq = rand_range(0.3, 0.9)
|
||||
p_freq_limit = rand_range(0, 0.1)
|
||||
p_freq_ramp = rand_range(-0.65, -0.35)
|
||||
if randi() % 2:
|
||||
p_duty = randf_range(0, 0.5)
|
||||
p_duty_ramp = randf_range(0, 0.2)
|
||||
p_duty = rand_range(0, 0.5)
|
||||
p_duty_ramp = rand_range(0, 0.2)
|
||||
else:
|
||||
p_duty = randf_range(0.4, 0.9)
|
||||
p_duty_ramp = randf_range(-0.7, 0)
|
||||
p_duty = rand_range(0.4, 0.9)
|
||||
p_duty_ramp = rand_range(-0.7, 0)
|
||||
p_env_attack = 0.0
|
||||
p_env_sustain = randf_range(0.1, 0.3)
|
||||
p_env_decay = randf_range(0.0, 0.4)
|
||||
p_env_sustain = rand_range(0.1, 0.3)
|
||||
p_env_decay = rand_range(0.0, 0.4)
|
||||
if randi() % 2:
|
||||
p_env_punch = randf_range(0, 0.3)
|
||||
p_env_punch = rand_range(0, 0.3)
|
||||
if randi() % 3 == 0:
|
||||
p_pha_offset = randf_range(0, 0.2)
|
||||
p_pha_ramp = randf_range(0, 0.2)
|
||||
p_pha_offset = rand_range(0, 0.2)
|
||||
p_pha_ramp = rand_range(0, 0.2)
|
||||
if randi() % 2:
|
||||
p_hpf_freq = randf_range(0, 0.3)
|
||||
p_hpf_freq = rand_range(0, 0.3)
|
||||
|
||||
Category.EXPLOSION:
|
||||
wave_type = WaveType.NOISE
|
||||
if randi() % 2:
|
||||
p_base_freq = randf_range(0.1, 0.4)
|
||||
p_freq_ramp = randf_range(-0.1, 0.3)
|
||||
p_base_freq = rand_range(0.1, 0.4)
|
||||
p_freq_ramp = rand_range(-0.1, 0.3)
|
||||
else:
|
||||
p_base_freq = randf_range(0.2, 0.9)
|
||||
p_freq_ramp = randf_range(-0.4, -0.2)
|
||||
p_base_freq = rand_range(0.2, 0.9)
|
||||
p_freq_ramp = rand_range(-0.4, -0.2)
|
||||
p_base_freq *= p_base_freq
|
||||
if randi() % 5 == 0:
|
||||
p_freq_ramp = 0.0
|
||||
if randi() % 3 == 0:
|
||||
p_repeat_speed = randf_range(0.3, 0.8)
|
||||
p_repeat_speed = rand_range(0.3, 0.8)
|
||||
p_env_attack = 0.0
|
||||
p_env_sustain = randf_range(0.1, 0.4)
|
||||
p_env_decay = randf_range(0, 0.5)
|
||||
p_env_sustain = rand_range(0.1, 0.4)
|
||||
p_env_decay = rand_range(0, 0.5)
|
||||
if randi() % 2:
|
||||
p_pha_offset = randf_range(-0.3, 0.6)
|
||||
p_pha_ramp = randf_range(-0.3, 0)
|
||||
p_env_punch = randf_range(0.2, 0.8)
|
||||
p_pha_offset = rand_range(-0.3, 0.6)
|
||||
p_pha_ramp = rand_range(-0.3, 0)
|
||||
p_env_punch = rand_range(0.2, 0.8)
|
||||
if randi() % 2:
|
||||
p_vib_strength = randf_range(0, 0.7)
|
||||
p_vib_speed = randf_range(0, 0.6)
|
||||
p_vib_strength = rand_range(0, 0.7)
|
||||
p_vib_speed = rand_range(0, 0.6)
|
||||
if randi() % 3:
|
||||
p_arp_speed = randf_range(0.6, 0.9)
|
||||
p_arp_mod = randf_range(-0.8, 0.8)
|
||||
p_arp_speed = rand_range(0.6, 0.9)
|
||||
p_arp_mod = rand_range(-0.8, 0.8)
|
||||
|
||||
Category.POWERUP:
|
||||
if randi() % 2:
|
||||
wave_type = WaveType.SAWTOOTH
|
||||
else:
|
||||
p_duty = randf_range(0, 0.6)
|
||||
p_duty = rand_range(0, 0.6)
|
||||
if randi() % 2:
|
||||
p_base_freq = randf_range(0.2, 0.5)
|
||||
p_freq_ramp = randf_range(0.1, 0.5)
|
||||
p_repeat_speed = randf_range(0.4, 0.8)
|
||||
p_base_freq = rand_range(0.2, 0.5)
|
||||
p_freq_ramp = rand_range(0.1, 0.5)
|
||||
p_repeat_speed = rand_range(0.4, 0.8)
|
||||
else:
|
||||
p_base_freq = randf_range(0.2, 0.5)
|
||||
p_freq_ramp = randf_range(0.05, 0.25)
|
||||
p_base_freq = rand_range(0.2, 0.5)
|
||||
p_freq_ramp = rand_range(0.05, 0.25)
|
||||
if randi() % 2:
|
||||
p_vib_strength = randf_range(0, 0.7)
|
||||
p_vib_speed = randf_range(0, 0.6)
|
||||
p_vib_strength = rand_range(0, 0.7)
|
||||
p_vib_speed = rand_range(0, 0.6)
|
||||
p_env_attack = 0.0
|
||||
p_env_sustain = randf_range(0, 0.4)
|
||||
p_env_decay = randf_range(0.1, 0.5)
|
||||
p_env_sustain = rand_range(0, 0.4)
|
||||
p_env_decay = rand_range(0.1, 0.5)
|
||||
|
||||
Category.HIT_HURT:
|
||||
wave_type = randi() % 3
|
||||
@ -241,123 +243,123 @@ func randomize_in_category(category: int) -> void:
|
||||
WaveType.SINE_WAVE:
|
||||
wave_type = WaveType.NOISE
|
||||
WaveType.SQUARE_WAVE:
|
||||
p_duty = randf_range(0, 0.6)
|
||||
p_base_freq = randf_range(0.2, 0.8)
|
||||
p_freq_ramp = randf_range(-0.7, -0.3)
|
||||
p_duty = rand_range(0, 0.6)
|
||||
p_base_freq = rand_range(0.2, 0.8)
|
||||
p_freq_ramp = rand_range(-0.7, -0.3)
|
||||
p_env_attack = 0.0
|
||||
p_env_sustain = randf_range(0, 0.1)
|
||||
p_env_decay = randf_range(0.1, 0.3)
|
||||
p_env_sustain = rand_range(0, 0.1)
|
||||
p_env_decay = rand_range(0.1, 0.3)
|
||||
if randi() % 2:
|
||||
p_hpf_freq = randf_range(0, 0.3)
|
||||
p_hpf_freq = rand_range(0, 0.3)
|
||||
|
||||
Category.JUMP:
|
||||
wave_type = WaveType.SQUARE_WAVE
|
||||
p_duty = randf_range(0, 0.6)
|
||||
p_base_freq = randf_range(0.3, 0.6)
|
||||
p_freq_ramp = randf_range(0.1, 0.3)
|
||||
p_duty = rand_range(0, 0.6)
|
||||
p_base_freq = rand_range(0.3, 0.6)
|
||||
p_freq_ramp = rand_range(0.1, 0.3)
|
||||
p_env_attack = 0.0
|
||||
p_env_sustain = randf_range(0.1, 0.4)
|
||||
p_env_decay = randf_range(0.1, 0.3)
|
||||
p_env_sustain = rand_range(0.1, 0.4)
|
||||
p_env_decay = rand_range(0.1, 0.3)
|
||||
if randi() % 2:
|
||||
p_hpf_freq = randf_range(0, 0.3)
|
||||
p_hpf_freq = rand_range(0, 0.3)
|
||||
if randi() % 2:
|
||||
p_lpf_freq = randf_range(0.4, 1.0)
|
||||
p_lpf_freq = rand_range(0.4, 1.0)
|
||||
|
||||
Category.BLIP_SELECT:
|
||||
wave_type = randi() % 2
|
||||
if wave_type == WaveType.SQUARE_WAVE:
|
||||
p_duty = randf_range(0, 0.6)
|
||||
p_base_freq = randf_range(0.2, 0.6)
|
||||
p_duty = rand_range(0, 0.6)
|
||||
p_base_freq = rand_range(0.2, 0.6)
|
||||
p_env_attack = 0.0
|
||||
p_env_sustain = randf_range(0.1, 0.2)
|
||||
p_env_decay = randf_range(0, 0.2)
|
||||
p_env_sustain = rand_range(0.1, 0.2)
|
||||
p_env_decay = rand_range(0, 0.2)
|
||||
p_hpf_freq = 0.1
|
||||
|
||||
|
||||
func randomize() -> void:
|
||||
p_base_freq = pow(randf_range(-1.0, +1.0), 2.0)
|
||||
p_base_freq = pow(rand_range(-1.0, +1.0), 2.0)
|
||||
if randi() % 2:
|
||||
p_base_freq = pow(randf_range(-1.0, +1.0), 3.0) + 0.5
|
||||
p_base_freq = pow(rand_range(-1.0, +1.0), 3.0) + 0.5
|
||||
p_freq_limit = 0.0
|
||||
p_freq_ramp = pow(randf_range(-1.0, +1.0), 5.0)
|
||||
p_freq_ramp = pow(rand_range(-1.0, +1.0), 5.0)
|
||||
if p_base_freq > 0.7 and p_freq_ramp > 0.2:
|
||||
p_freq_ramp = -p_freq_ramp
|
||||
if p_base_freq < 0.2 and p_freq_ramp < -0.05:
|
||||
p_freq_ramp = -p_freq_ramp
|
||||
p_freq_dramp = pow(randf_range(-1.0, +1.0), 3.0)
|
||||
p_duty = randf_range(-1.0, +1.0)
|
||||
p_duty_ramp = pow(randf_range(-1.0, +1.0), 3.0)
|
||||
p_vib_strength = pow(randf_range(-1.0, +1.0), 3.0)
|
||||
p_vib_speed = randf_range(-1.0, +1.0)
|
||||
# p_vib_delay = randf_range(-1.0, +1.0)
|
||||
p_env_attack = pow(randf_range(-1.0, +1.0), 3.0)
|
||||
p_env_sustain = pow(randf_range(-1.0, +1.0), 2.0)
|
||||
p_env_decay = randf_range(-1.0, +1.0)
|
||||
p_env_punch = pow(randf_range(0, 0.8), 2.0)
|
||||
p_freq_dramp = pow(rand_range(-1.0, +1.0), 3.0)
|
||||
p_duty = rand_range(-1.0, +1.0)
|
||||
p_duty_ramp = pow(rand_range(-1.0, +1.0), 3.0)
|
||||
p_vib_strength = pow(rand_range(-1.0, +1.0), 3.0)
|
||||
p_vib_speed = rand_range(-1.0, +1.0)
|
||||
# p_vib_delay = rand_range(-1.0, +1.0)
|
||||
p_env_attack = pow(rand_range(-1.0, +1.0), 3.0)
|
||||
p_env_sustain = pow(rand_range(-1.0, +1.0), 2.0)
|
||||
p_env_decay = rand_range(-1.0, +1.0)
|
||||
p_env_punch = pow(rand_range(0, 0.8), 2.0)
|
||||
if p_env_attack + p_env_sustain + p_env_decay < 0.2:
|
||||
p_env_sustain += randf_range(0.2, 0.5)
|
||||
p_env_decay += randf_range(0.2, 0.5)
|
||||
p_lpf_resonance = randf_range(-1.0, +1.0)
|
||||
p_env_sustain += rand_range(0.2, 0.5)
|
||||
p_env_decay += rand_range(0.2, 0.5)
|
||||
p_lpf_resonance = rand_range(-1.0, +1.0)
|
||||
p_lpf_freq = 1.0 - pow(randf(), 3.0)
|
||||
p_lpf_ramp = pow(randf_range(-1.0, +1.0), 3.0)
|
||||
p_lpf_ramp = pow(rand_range(-1.0, +1.0), 3.0)
|
||||
if p_lpf_freq < 0.1 and p_lpf_ramp < -0.05:
|
||||
p_lpf_ramp = -p_lpf_ramp
|
||||
p_hpf_freq = pow(randf(), 5.0)
|
||||
p_hpf_ramp = pow(randf_range(-1.0, +1.0), 5.0)
|
||||
p_pha_offset = pow(randf_range(-1.0, +1.0), 3.0)
|
||||
p_pha_ramp = pow(randf_range(-1.0, +1.0), 3.0)
|
||||
p_repeat_speed = randf_range(-1.0, +1.0)
|
||||
p_arp_speed = randf_range(-1.0, +1.0)
|
||||
p_arp_mod = randf_range(-1.0, +1.0)
|
||||
p_hpf_ramp = pow(rand_range(-1.0, +1.0), 5.0)
|
||||
p_pha_offset = pow(rand_range(-1.0, +1.0), 3.0)
|
||||
p_pha_ramp = pow(rand_range(-1.0, +1.0), 3.0)
|
||||
p_repeat_speed = rand_range(-1.0, +1.0)
|
||||
p_arp_speed = rand_range(-1.0, +1.0)
|
||||
p_arp_mod = rand_range(-1.0, +1.0)
|
||||
|
||||
|
||||
func mutate() -> void:
|
||||
if randi() % 2:
|
||||
p_base_freq += randf_range(-0.05, +0.05)
|
||||
p_base_freq += rand_range(-0.05, +0.05)
|
||||
if randi() % 2:
|
||||
p_freq_limit += randf_range(-0.05, +0.05)
|
||||
p_freq_limit += rand_range(-0.05, +0.05)
|
||||
if randi() % 2:
|
||||
p_freq_ramp += randf_range(-0.05, +0.05)
|
||||
p_freq_ramp += rand_range(-0.05, +0.05)
|
||||
if randi() % 2:
|
||||
p_freq_dramp += randf_range(-0.05, +0.05)
|
||||
p_freq_dramp += rand_range(-0.05, +0.05)
|
||||
if randi() % 2:
|
||||
p_duty += randf_range(-0.05, +0.05)
|
||||
p_duty += rand_range(-0.05, +0.05)
|
||||
if randi() % 2:
|
||||
p_duty_ramp += randf_range(-0.05, +0.05)
|
||||
p_duty_ramp += rand_range(-0.05, +0.05)
|
||||
if randi() % 2:
|
||||
p_vib_strength += randf_range(-0.05, +0.05)
|
||||
p_vib_strength += rand_range(-0.05, +0.05)
|
||||
if randi() % 2:
|
||||
p_vib_speed += randf_range(-0.05, +0.05)
|
||||
p_vib_speed += rand_range(-0.05, +0.05)
|
||||
# if randi() % 2:
|
||||
# p_vib_delay += randf_range(-0.05, +0.05)
|
||||
# p_vib_delay += rand_range(-0.05, +0.05)
|
||||
if randi() % 2:
|
||||
p_env_attack += randf_range(-0.05, +0.05)
|
||||
p_env_attack += rand_range(-0.05, +0.05)
|
||||
if randi() % 2:
|
||||
p_env_sustain += randf_range(-0.05, +0.05)
|
||||
p_env_sustain += rand_range(-0.05, +0.05)
|
||||
if randi() % 2:
|
||||
p_env_decay += randf_range(-0.05, +0.05)
|
||||
p_env_decay += rand_range(-0.05, +0.05)
|
||||
if randi() % 2:
|
||||
p_env_punch += randf_range(-0.05, +0.05)
|
||||
p_env_punch += rand_range(-0.05, +0.05)
|
||||
if randi() % 2:
|
||||
p_lpf_resonance += randf_range(-0.05, +0.05)
|
||||
p_lpf_resonance += rand_range(-0.05, +0.05)
|
||||
if randi() % 2:
|
||||
p_lpf_freq += randf_range(-0.05, +0.05)
|
||||
p_lpf_freq += rand_range(-0.05, +0.05)
|
||||
if randi() % 2:
|
||||
p_lpf_ramp += randf_range(-0.05, +0.05)
|
||||
p_lpf_ramp += rand_range(-0.05, +0.05)
|
||||
if randi() % 2:
|
||||
p_hpf_freq += randf_range(-0.05, +0.05)
|
||||
p_hpf_freq += rand_range(-0.05, +0.05)
|
||||
if randi() % 2:
|
||||
p_hpf_ramp += randf_range(-0.05, +0.05)
|
||||
p_hpf_ramp += rand_range(-0.05, +0.05)
|
||||
if randi() % 2:
|
||||
p_pha_offset += randf_range(-0.05, +0.05)
|
||||
p_pha_offset += rand_range(-0.05, +0.05)
|
||||
if randi() % 2:
|
||||
p_pha_ramp += randf_range(-0.05, +0.05)
|
||||
p_pha_ramp += rand_range(-0.05, +0.05)
|
||||
if randi() % 2:
|
||||
p_repeat_speed += randf_range(-0.05, +0.05)
|
||||
p_repeat_speed += rand_range(-0.05, +0.05)
|
||||
if randi() % 2:
|
||||
p_arp_speed += randf_range(-0.05, +0.05)
|
||||
p_arp_speed += rand_range(-0.05, +0.05)
|
||||
if randi() % 2:
|
||||
p_arp_mod += randf_range(-0.05, +0.05)
|
||||
p_arp_mod += rand_range(-0.05, +0.05)
|
||||
|
||||
|
||||
func reset():
|
||||
@ -395,7 +397,7 @@ func reset():
|
||||
p_arp_mod = 0.0
|
||||
|
||||
|
||||
func copy_from(other: RefCounted) -> void: # SFXRConfig
|
||||
func copy_from(other: Reference) -> void: # SFXRConfig
|
||||
wave_type = other.wave_type
|
||||
|
||||
p_env_attack = other.p_env_attack
|
||||
@ -430,7 +432,7 @@ func copy_from(other: RefCounted) -> void: # SFXRConfig
|
||||
sound_vol = other.sound_vol
|
||||
|
||||
|
||||
func is_equal(other: RefCounted) -> bool: # SFXRConfig
|
||||
func is_equal(other: Reference) -> bool: # SFXRConfig
|
||||
return (
|
||||
wave_type == other.wave_type
|
||||
|
||||
|
@ -32,15 +32,15 @@ var vib_speed: float
|
||||
var square_duty: float
|
||||
var square_slide: float
|
||||
var env_vol: float
|
||||
var env_length := PackedInt32Array([0, 0, 0])
|
||||
var env_length := PoolIntArray([0, 0, 0])
|
||||
var phase: int
|
||||
var fphase: float
|
||||
var fdphase: float
|
||||
var iphase: int
|
||||
var flthp: float
|
||||
var flthp_d: float
|
||||
var noise_buffer := PackedFloat32Array([])
|
||||
var phaser_buffer := PackedFloat32Array([])
|
||||
var noise_buffer := PoolRealArray([])
|
||||
var phaser_buffer := PoolRealArray([])
|
||||
var ipp: int
|
||||
var fltp: float
|
||||
var fltdp: float
|
||||
@ -54,9 +54,9 @@ func generate_audio_stream(
|
||||
config: SFXRConfig,
|
||||
wav_bits: int = WavBits.WAV_BITS_8,
|
||||
wav_freq: int = WavFreq.WAV_FREQ_44100
|
||||
) -> AudioStreamWAV:
|
||||
var stream := AudioStreamWAV.new()
|
||||
stream.format = AudioStreamWAV.FORMAT_8_BITS if wav_bits == WavBits.WAV_BITS_8 else AudioStreamWAV.FORMAT_16_BITS
|
||||
) -> AudioStreamSample:
|
||||
var stream := AudioStreamSample.new()
|
||||
stream.format = AudioStreamSample.FORMAT_8_BITS if wav_bits == WavBits.WAV_BITS_8 else AudioStreamSample.FORMAT_16_BITS
|
||||
stream.mix_rate = 44100 if wav_freq == WavFreq.WAV_FREQ_44100 else 22050
|
||||
|
||||
_config = config
|
||||
@ -70,7 +70,7 @@ func generate_samples(
|
||||
config: SFXRConfig,
|
||||
wav_bits: int = WavBits.WAV_BITS_8,
|
||||
wav_freq: int = WavFreq.WAV_FREQ_44100
|
||||
) -> PackedByteArray:
|
||||
) -> PoolByteArray:
|
||||
_config = config
|
||||
var data := _generate_samples(wav_bits, wav_freq).data_array
|
||||
_config = null
|
||||
@ -148,7 +148,7 @@ func _generate_samples(wav_bits: int, wav_freq: int) -> StreamPeerBuffer:
|
||||
phase %= period
|
||||
if _config.wave_type == SFXRConfig.WaveType.NOISE:
|
||||
for j in 32:
|
||||
noise_buffer[j] = randf_range(-1.0, +1.0)
|
||||
noise_buffer[j] = rand_range(-1.0, +1.0)
|
||||
|
||||
# base waveform
|
||||
var fp := float(phase) / period
|
||||
@ -266,7 +266,7 @@ func _reset_sample(restart: bool) -> void:
|
||||
|
||||
noise_buffer.resize(32)
|
||||
for i in noise_buffer.size():
|
||||
noise_buffer[i] = randf_range(-1.0, +1.0)
|
||||
noise_buffer[i] = rand_range(-1.0, +1.0)
|
||||
|
||||
rep_time = 0
|
||||
rep_limit = int(pow(1.0 - _config.p_repeat_speed, 2.0) * 20000 + 32)
|
||||
|
@ -1,12 +1,11 @@
|
||||
@tool
|
||||
tool
|
||||
extends Control
|
||||
|
||||
signal value_changed(value)
|
||||
|
||||
@export var value: float = 0.0 :
|
||||
set = set_value
|
||||
@export var min_value: float = 0.0
|
||||
@export var max_value: float = 1.0
|
||||
export var value: float = 0.0 setget set_value
|
||||
export var min_value: float = 0.0
|
||||
export var max_value: float = 1.0
|
||||
|
||||
var _line_edit: LineEdit
|
||||
|
||||
@ -18,7 +17,6 @@ var _stylebox_value: StyleBox
|
||||
var _line_edit_just_closed := false
|
||||
var _mouse_hovering := false
|
||||
var _is_editing := false
|
||||
var _is_cancel := false
|
||||
|
||||
var _drag_start_position: Vector2
|
||||
var _drag_cancelled := true
|
||||
@ -26,9 +24,9 @@ var _drag_dist := 0.0
|
||||
var _drag_start_factor: float
|
||||
|
||||
|
||||
func _init():
|
||||
func _init() -> void:
|
||||
mouse_default_cursor_shape = Control.CURSOR_HSIZE
|
||||
clip_contents = true
|
||||
rect_clip_content = true
|
||||
focus_mode = Control.FOCUS_ALL
|
||||
|
||||
var style := StyleBoxEmpty.new()
|
||||
@ -36,51 +34,49 @@ func _init():
|
||||
style.content_margin_right = 8
|
||||
|
||||
_line_edit = LineEdit.new()
|
||||
_line_edit.set_as_top_level(true)
|
||||
_line_edit.set_as_toplevel(true)
|
||||
_line_edit.visible = false
|
||||
_line_edit.add_theme_stylebox_override("normal", style)
|
||||
_line_edit.add_theme_stylebox_override("focus", StyleBoxEmpty.new())
|
||||
|
||||
var _ret: int
|
||||
_ret = _line_edit.focus_exited.connect(self._on_line_edit_focus_exited)
|
||||
_ret = _line_edit.text_submitted.connect(self._on_line_edit_text_entered)
|
||||
_ret = _line_edit.visibility_changed.connect(self._on_line_edit_visibility_changed)
|
||||
_ret = _line_edit.gui_input.connect(self._on_line_edit_gui_input)
|
||||
_ret = _line_edit.connect("focus_exited", self, "_on_line_edit_focus_exited")
|
||||
_ret = _line_edit.connect("text_entered", self, "_on_line_edit_text_entered")
|
||||
_ret = _line_edit.connect("visibility_changed", self, "_on_line_edit_visibility_changed")
|
||||
|
||||
add_child(_line_edit)
|
||||
|
||||
|
||||
func _draw() -> void:
|
||||
var font := get_theme_font("font", "LineEdit")
|
||||
var font_size := get_theme_font_size("font_size", "LineEdit")
|
||||
var color := get_theme_color("highlighted_font_color" if _mouse_hovering else "font_color", "Editor")
|
||||
var number_string := "%.3f" % value
|
||||
var number_size := font.get_string_size(number_string)
|
||||
var pos := Vector2(
|
||||
(size.x - number_size.x) / 2,
|
||||
(size.y - number_size.y) / 2 + font.get_ascent()
|
||||
(rect_size.x - number_size.x) / 2,
|
||||
(rect_size.y - number_size.y) / 2 + font.get_ascent()
|
||||
)
|
||||
|
||||
var stylebox := _stylebox_editing if _is_editing else _stylebox_hover if _mouse_hovering else _stylebox_normal
|
||||
|
||||
if _line_edit.visible:
|
||||
draw_style_box(stylebox, Rect2(Vector2.ZERO, size))
|
||||
draw_style_box(stylebox, Rect2(Vector2.ZERO, rect_size))
|
||||
else:
|
||||
var value_width := size.x * ((value - min_value) / (max_value - min_value))
|
||||
draw_style_box(stylebox, Rect2(value_width, 0, size.x - value_width, size.y))
|
||||
draw_style_box(_stylebox_value, Rect2(0, 0, value_width, size.y))
|
||||
draw_string(font, pos, number_string, HORIZONTAL_ALIGNMENT_CENTER, -1, font_size, color)
|
||||
var value_width := rect_size.x * ((value - min_value) / (max_value - min_value))
|
||||
draw_style_box(stylebox, Rect2(value_width, 0, rect_size.x - value_width, rect_size.y))
|
||||
draw_style_box(_stylebox_value, Rect2(0, 0, value_width, rect_size.y))
|
||||
draw_string(font, pos, number_string, color)
|
||||
|
||||
|
||||
func _get_minimum_size() -> Vector2:
|
||||
var ms := _stylebox_normal.get_minimum_size() if _stylebox_normal else Vector2.ZERO
|
||||
var ms := _stylebox_normal.get_minimum_size()
|
||||
ms.y += get_theme_font("font", "LineEdit").get_height()
|
||||
return ms
|
||||
|
||||
|
||||
func _gui_input(event: InputEvent) -> void:
|
||||
var mb := event as InputEventMouseButton
|
||||
if mb and mb.button_index == MOUSE_BUTTON_LEFT:
|
||||
if mb and mb.button_index == BUTTON_LEFT:
|
||||
if mb.pressed:
|
||||
_drag_prepare(mb)
|
||||
else:
|
||||
@ -89,10 +85,10 @@ func _gui_input(event: InputEvent) -> void:
|
||||
_show_text_edit()
|
||||
_drag_cancelled = true
|
||||
_is_editing = mb.pressed
|
||||
queue_redraw()
|
||||
update()
|
||||
|
||||
var mm := event as InputEventMouseMotion
|
||||
if mm and mm.button_mask & MOUSE_BUTTON_MASK_LEFT:
|
||||
if mm and mm.button_mask & BUTTON_MASK_LEFT:
|
||||
_drag_motion(mm)
|
||||
_drag_cancelled = false
|
||||
|
||||
@ -104,11 +100,11 @@ func _notification(what: int) -> void:
|
||||
|
||||
NOTIFICATION_MOUSE_ENTER:
|
||||
_mouse_hovering = true
|
||||
queue_redraw()
|
||||
update()
|
||||
|
||||
NOTIFICATION_MOUSE_EXIT:
|
||||
_mouse_hovering = false
|
||||
queue_redraw()
|
||||
update()
|
||||
|
||||
NOTIFICATION_FOCUS_ENTER:
|
||||
if (Input.is_action_pressed("ui_focus_next") or Input.is_action_pressed("ui_focus_prev")) and not _line_edit_just_closed:
|
||||
@ -121,7 +117,7 @@ func set_value(v: float) -> void:
|
||||
return
|
||||
value = v
|
||||
emit_signal("value_changed", value)
|
||||
queue_redraw()
|
||||
update()
|
||||
|
||||
|
||||
func _update_stylebox() -> void:
|
||||
@ -145,9 +141,9 @@ func _drag_done() -> void:
|
||||
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
|
||||
|
||||
if _drag_cancelled:
|
||||
Input.warp_mouse(_drag_start_position)
|
||||
Input.warp_mouse_position(_drag_start_position)
|
||||
else:
|
||||
Input.warp_mouse(global_position + size * Vector2(
|
||||
Input.warp_mouse_position(rect_global_position + rect_size * Vector2(
|
||||
(value - min_value) / (max_value - min_value),
|
||||
0.5
|
||||
))
|
||||
@ -156,33 +152,32 @@ func _drag_done() -> void:
|
||||
func _drag_motion(motion: InputEventMouseMotion) -> void:
|
||||
_drag_dist += motion.relative.x
|
||||
|
||||
var factor := _drag_start_factor + _drag_dist / size.x
|
||||
var factor := _drag_start_factor + _drag_dist / rect_size.x
|
||||
if factor < 0 or 1 < factor:
|
||||
factor = clamp(factor, 0, 1)
|
||||
_drag_dist = (factor - _drag_start_factor) * size.x
|
||||
_drag_dist = (factor - _drag_start_factor) * rect_size.x
|
||||
|
||||
var v := factor * (max_value - min_value) + min_value
|
||||
var snap := motion.is_command_or_control_pressed() or motion.shift_pressed
|
||||
var snap := motion.command or motion.shift
|
||||
if snap and not (is_equal_approx(v, min_value) or is_equal_approx(v, max_value)):
|
||||
if motion.shift_pressed and motion.is_command_or_control_pressed():
|
||||
if motion.shift and motion.command:
|
||||
v = round(v * 1000.0) * 0.001
|
||||
elif motion.shift_pressed:
|
||||
elif motion.shift:
|
||||
v = round(v * 100.0) * 0.01
|
||||
else:
|
||||
v = round(v * 10.0) * 0.1
|
||||
|
||||
set_value(clamp(v, min_value, max_value))
|
||||
|
||||
queue_redraw()
|
||||
update()
|
||||
|
||||
|
||||
func _show_text_edit() -> void:
|
||||
var gr := get_global_rect()
|
||||
_is_cancel = false
|
||||
_line_edit.text = str(value)
|
||||
_line_edit.set_position(gr.position)
|
||||
_line_edit.set_size(gr.size)
|
||||
_line_edit.show() # FIXME: no suitable solution for `show_modal` yet
|
||||
_line_edit.show_modal()
|
||||
_line_edit.select_all()
|
||||
_line_edit.grab_focus()
|
||||
_line_edit.focus_next = find_next_valid_focus().get_path()
|
||||
@ -192,11 +187,11 @@ func _show_text_edit() -> void:
|
||||
func _on_line_edit_focus_exited():
|
||||
if _line_edit.get_menu().visible:
|
||||
return
|
||||
if not _is_cancel and _line_edit.text.is_valid_float():
|
||||
if _line_edit.text.is_valid_float():
|
||||
set_value(clamp(_line_edit.text.to_float(), min_value, max_value))
|
||||
if not _line_edit_just_closed:
|
||||
_line_edit.hide()
|
||||
queue_redraw()
|
||||
update()
|
||||
|
||||
|
||||
func _on_line_edit_text_entered(_text: String):
|
||||
@ -206,9 +201,3 @@ func _on_line_edit_text_entered(_text: String):
|
||||
func _on_line_edit_visibility_changed():
|
||||
if not _line_edit.visible:
|
||||
_line_edit_just_closed = true
|
||||
|
||||
|
||||
func _on_line_edit_gui_input(event: InputEvent):
|
||||
if event.is_action_pressed("ui_cancel"):
|
||||
_is_cancel = true
|
||||
_line_edit.hide()
|
||||
|
@ -1,4 +1,4 @@
|
||||
@tool
|
||||
tool
|
||||
extends Container
|
||||
|
||||
enum ExtraOption { SAVE_AS, COPY, PASTE, PASTE_JSFXR, RECENT }
|
||||
@ -13,11 +13,7 @@ class RecentEntry:
|
||||
var title: String
|
||||
var config := SFXRConfig.new()
|
||||
|
||||
var plugin: EditorPlugin:
|
||||
set(v):
|
||||
plugin = v
|
||||
for child in get_children():
|
||||
_hook_plugin(child)
|
||||
var plugin: EditorPlugin
|
||||
|
||||
var _config := SFXRConfig.new()
|
||||
var _config_defaults := SFXRConfig.new()
|
||||
@ -31,44 +27,47 @@ var _param_map := {}
|
||||
var _syncing_ui := false # a hack since Range set_value emits value_changed
|
||||
var _category_names := {}
|
||||
|
||||
@onready var audio_player := $AudioStreamPlayer as AudioStreamPlayer
|
||||
@onready var filename_label := find_child("Filename") as Label
|
||||
@onready var save_button := find_child("Save") as Button
|
||||
@onready var restore_button := find_child("Restore") as Button
|
||||
@onready var extra_button := find_child("Extra") as MenuButton
|
||||
@onready var version_button := find_child("VersionButton")
|
||||
@onready var translator := $PluginTranslator
|
||||
onready var audio_player := $AudioStreamPlayer as AudioStreamPlayer
|
||||
onready var filename_label := find_node("Filename") as Label
|
||||
onready var save_button := find_node("Save") as Button
|
||||
onready var restore_button := find_node("Restore") as Button
|
||||
onready var extra_button := find_node("Extra") as MenuButton
|
||||
onready var version_button := find_node("VersionButton")
|
||||
onready var translator := $PluginTranslator
|
||||
|
||||
|
||||
func _ready():
|
||||
if not plugin:
|
||||
return # Running in the edited scene instead of from Plugin
|
||||
|
||||
for child in get_children():
|
||||
_hook_plugin(child)
|
||||
|
||||
var popup := extra_button.get_popup()
|
||||
popup.add_item(translator.t("Save As..."), ExtraOption.SAVE_AS)
|
||||
popup.add_item(translator.tr("Save As..."), ExtraOption.SAVE_AS)
|
||||
popup.add_separator()
|
||||
popup.add_icon_item(get_theme_icon("ActionCopy", "EditorIcons"), translator.t("Copy"), ExtraOption.COPY)
|
||||
popup.add_icon_item(get_theme_icon("ActionPaste", "EditorIcons"), translator.t("Paste"), ExtraOption.PASTE)
|
||||
popup.add_item(translator.t("Paste from jsfxr"), ExtraOption.PASTE_JSFXR)
|
||||
popup.add_separator(translator.t("Recently Generated"))
|
||||
popup.id_pressed.connect(_on_Extra_id_pressed)
|
||||
popup.add_item(translator.tr("Copy"), ExtraOption.COPY)
|
||||
popup.add_item(translator.tr("Paste"), ExtraOption.PASTE)
|
||||
popup.add_item(translator.tr("Paste from jsfxr"), ExtraOption.PASTE_JSFXR)
|
||||
popup.add_separator(translator.tr("Recently Generated"))
|
||||
popup.connect("id_pressed", self, "_on_Extra_id_pressed")
|
||||
|
||||
_category_names = {
|
||||
SFXRConfig.Category.PICKUP_COIN: translator.t("Pickup/Coin"),
|
||||
SFXRConfig.Category.LASER_SHOOT: translator.t("Laser/Shoot"),
|
||||
SFXRConfig.Category.EXPLOSION: translator.t("Explosion"),
|
||||
SFXRConfig.Category.POWERUP: translator.t("Powerup"),
|
||||
SFXRConfig.Category.HIT_HURT: translator.t("Hit/Hurt"),
|
||||
SFXRConfig.Category.JUMP: translator.t("Jump"),
|
||||
SFXRConfig.Category.BLIP_SELECT: translator.t("Blip/Select"),
|
||||
SFXRConfig.Category.PICKUP_COIN: translator.tr("Pickup/Coin"),
|
||||
SFXRConfig.Category.LASER_SHOOT: translator.tr("Laser/Shoot"),
|
||||
SFXRConfig.Category.EXPLOSION: translator.tr("Explosion"),
|
||||
SFXRConfig.Category.POWERUP: translator.tr("Powerup"),
|
||||
SFXRConfig.Category.HIT_HURT: translator.tr("Hit/Hurt"),
|
||||
SFXRConfig.Category.JUMP: translator.tr("Jump"),
|
||||
SFXRConfig.Category.BLIP_SELECT: translator.tr("Blip/Select"),
|
||||
}
|
||||
|
||||
var params := find_child("Params") as Container
|
||||
var params := find_node("Params") as Container
|
||||
for category in params.get_children():
|
||||
for control in category.get_children():
|
||||
_param_map[control.parameter] = control
|
||||
control.connect("param_changed", _on_param_changed)
|
||||
control.connect("param_reset", _on_param_reset)
|
||||
control.connect("param_changed", self, "_on_param_changed")
|
||||
control.connect("param_reset", self, "_on_param_reset")
|
||||
|
||||
_set_editing_file("")
|
||||
|
||||
@ -79,7 +78,7 @@ func _notification(what: int):
|
||||
|
||||
match what:
|
||||
NOTIFICATION_ENTER_TREE, NOTIFICATION_THEME_CHANGED:
|
||||
find_child("ScrollContainer").add_theme_stylebox_override("panel", get_theme_stylebox("panel", "Tree"))
|
||||
find_node("ScrollContainer").add_theme_stylebox_override("bg", get_theme_stylebox("bg", "Tree"))
|
||||
|
||||
if extra_button:
|
||||
var popup = extra_button.get_popup()
|
||||
@ -87,18 +86,11 @@ func _notification(what: int):
|
||||
popup.set_item_icon(popup.get_item_index(ExtraOption.PASTE), get_theme_icon("ActionPaste", "EditorIcons"))
|
||||
|
||||
|
||||
func edit(object: Variant) -> void:
|
||||
if not object:
|
||||
if not _modified:
|
||||
_set_editing_file("")
|
||||
# TODO: prompt?
|
||||
return
|
||||
|
||||
var path := object.resource_path as String
|
||||
func edit(path: String) -> void:
|
||||
if _modified:
|
||||
_popup_confirm(
|
||||
translator.t("There are unsaved changes.\nOpen '%s' anyway?") % path,
|
||||
_set_editing_file.bind(path)
|
||||
str(translator.tr("There are unsaved changes.\nOpen '%s' anyway?")) % path,
|
||||
"_set_editing_file", [path]
|
||||
)
|
||||
else:
|
||||
_set_editing_file(path)
|
||||
@ -125,30 +117,30 @@ func _push_recent(title: String) -> void:
|
||||
_config_recents.push_front(recent)
|
||||
|
||||
|
||||
func _popup_confirm(content: String, callback: Callable) -> void:
|
||||
func _popup_confirm(content: String, callback: String, binds := []) -> void:
|
||||
var dialog := ConfirmationDialog.new()
|
||||
add_child(dialog)
|
||||
dialog.dialog_text = content
|
||||
dialog.title = translator.t("SFXR Editor")
|
||||
dialog.confirmed.connect(callback)
|
||||
dialog.window_title = translator.tr("SFXR Editor")
|
||||
dialog.connect("confirmed", self, callback, binds)
|
||||
dialog.connect("popup_hide", dialog, "queue_free")
|
||||
dialog.popup_centered()
|
||||
dialog.visibility_changed.connect(dialog.queue_free)
|
||||
|
||||
|
||||
func _popup_message(content: String) -> void:
|
||||
var dialog := AcceptDialog.new()
|
||||
add_child(dialog)
|
||||
dialog.dialog_text = content
|
||||
dialog.title = translator.t("SFXR Editor")
|
||||
dialog.window_title = translator.tr("SFXR Editor")
|
||||
dialog.connect("popup_hide", dialog, "queue_free")
|
||||
dialog.popup_centered()
|
||||
dialog.visibility_changed.connect(dialog.queue_free)
|
||||
|
||||
|
||||
func _popup_file_dialog(mode: int, callback: Callable, default_filename := DefaultFilename.EMPTY) -> void:
|
||||
func _popup_file_dialog(mode: int, callback: String, default_filename: int = DefaultFilename.EMPTY) -> void:
|
||||
var dialog := EditorFileDialog.new()
|
||||
add_child(dialog)
|
||||
dialog.access = EditorFileDialog.ACCESS_RESOURCES
|
||||
dialog.file_mode = mode
|
||||
dialog.mode = mode
|
||||
|
||||
match default_filename:
|
||||
DefaultFilename.EMPTY:
|
||||
@ -158,10 +150,10 @@ func _popup_file_dialog(mode: int, callback: Callable, default_filename := Defau
|
||||
if _path:
|
||||
dialog.current_path = _generate_serial_path(_path)
|
||||
|
||||
dialog.add_filter("*.sfxr; %s" % translator.t("SFXR Audio"))
|
||||
dialog.file_selected.connect(callback)
|
||||
dialog.add_filter("*.sfxr; %s" % translator.tr("SFXR Audio"))
|
||||
dialog.connect("popup_hide", dialog, "queue_free")
|
||||
dialog.connect("file_selected", self, callback)
|
||||
dialog.popup_centered_ratio()
|
||||
dialog.visibility_changed.connect(dialog.queue_free)
|
||||
|
||||
|
||||
func _reset_defaults() -> void:
|
||||
@ -178,13 +170,13 @@ func _restore_from_config(config: SFXRConfig) -> void:
|
||||
|
||||
|
||||
func _set_editing_file(path: String) -> int: # Error
|
||||
if path.is_empty():
|
||||
if path.empty():
|
||||
_config.reset()
|
||||
audio_player.stream = null
|
||||
else:
|
||||
var err := _config.load(path)
|
||||
if err != OK:
|
||||
_popup_message(translator.t("'%s' is not a valid SFXR file.") % path)
|
||||
_popup_message(str(translator.tr("'%s' is not a valid SFXR file.")) % path)
|
||||
return err
|
||||
audio_player.stream = load(path)
|
||||
|
||||
@ -196,8 +188,8 @@ func _set_editing_file(path: String) -> int: # Error
|
||||
func _set_modified(value: bool) -> void:
|
||||
_modified = value
|
||||
|
||||
var has_file := not _path.is_empty()
|
||||
var base = _path if has_file else translator.t("Unsaved sound")
|
||||
var has_file := not _path.empty()
|
||||
var base = _path if has_file else str(translator.tr("Unsaved sound"))
|
||||
if _modified:
|
||||
base += "(*)"
|
||||
filename_label.text = base
|
||||
@ -216,8 +208,8 @@ func _sync_ui() -> void:
|
||||
|
||||
|
||||
func _generate_serial_path(path: String) -> String:
|
||||
var directory := DirAccess.open(path.get_base_dir())
|
||||
if not directory:
|
||||
var directory := Directory.new()
|
||||
if directory.open(path.get_base_dir()) != OK:
|
||||
return path
|
||||
|
||||
if not directory.file_exists(path.get_file()):
|
||||
@ -281,7 +273,7 @@ func _on_Play_pressed(force_regenerate := false):
|
||||
func _on_Randomize_pressed(category: int):
|
||||
if category == -1:
|
||||
_config.randomize()
|
||||
_push_recent(translator.t("Randomize"))
|
||||
_push_recent(translator.tr("Randomize"))
|
||||
else:
|
||||
_config.randomize_in_category(category)
|
||||
_push_recent(_category_names.get(category, "Unknown"))
|
||||
@ -294,7 +286,7 @@ func _on_Randomize_pressed(category: int):
|
||||
func _on_Mutate_pressed():
|
||||
_config.mutate()
|
||||
|
||||
_push_recent(translator.t("Mutate"))
|
||||
_push_recent(translator.tr("Mutate"))
|
||||
_set_modified(true)
|
||||
_sync_ui()
|
||||
_on_Play_pressed(true)
|
||||
@ -307,8 +299,8 @@ func _on_Restore_pressed():
|
||||
func _on_New_pressed():
|
||||
if _modified:
|
||||
_popup_confirm(
|
||||
translator.t("There are unsaved changes.\nCreate a new one anyway?"),
|
||||
_on_New_confirmed
|
||||
translator.tr("There are unsaved changes.\nCreate a new one anyway?"),
|
||||
"_on_New_confirmed"
|
||||
)
|
||||
else:
|
||||
_on_New_confirmed()
|
||||
@ -319,8 +311,8 @@ func _on_New_confirmed() -> void:
|
||||
|
||||
|
||||
func _on_Save_pressed():
|
||||
if _path.is_empty():
|
||||
_popup_file_dialog(EditorFileDialog.FILE_MODE_SAVE_FILE, _on_SaveAsDialog_confirmed)
|
||||
if _path.empty():
|
||||
_popup_file_dialog(EditorFileDialog.MODE_SAVE_FILE, "_on_SaveAsDialog_confirmed")
|
||||
else:
|
||||
_config.save(_path)
|
||||
plugin.get_editor_interface().get_resource_filesystem().scan_sources()
|
||||
@ -337,17 +329,17 @@ func _on_SaveAsDialog_confirmed(path: String):
|
||||
func _on_Load_pressed():
|
||||
if _modified:
|
||||
_popup_confirm(
|
||||
translator.t("There are unsaved changes.\nLoad anyway?"),
|
||||
_popup_file_dialog.bind(EditorFileDialog.FILE_MODE_OPEN_FILE, "_set_editing_file")
|
||||
translator.tr("There are unsaved changes.\nLoad anyway?"),
|
||||
"_popup_file_dialog", [EditorFileDialog.MODE_OPEN_FILE, "_set_editing_file"]
|
||||
)
|
||||
else:
|
||||
_popup_file_dialog(EditorFileDialog.FILE_MODE_OPEN_FILE, _set_editing_file)
|
||||
_popup_file_dialog(EditorFileDialog.MODE_OPEN_FILE, "_set_editing_file")
|
||||
|
||||
|
||||
func _on_Extra_about_to_show():
|
||||
var popup := extra_button.get_popup()
|
||||
popup.set_item_disabled(popup.get_item_index(ExtraOption.PASTE), _config_clipboard == null)
|
||||
popup.set_item_disabled(popup.get_item_index(ExtraOption.PASTE_JSFXR), not DisplayServer.clipboard_has())
|
||||
popup.set_item_disabled(popup.get_item_index(ExtraOption.PASTE_JSFXR), not OS.has_clipboard())
|
||||
|
||||
# Rebuild recents menu everytime :)
|
||||
var first_recent_index := popup.get_item_index(ExtraOption.RECENT)
|
||||
@ -356,8 +348,8 @@ func _on_Extra_about_to_show():
|
||||
for i in count - first_recent_index:
|
||||
popup.remove_item(count - 1 - i)
|
||||
|
||||
if _config_recents.is_empty():
|
||||
popup.add_item(translator.t("None"), ExtraOption.RECENT)
|
||||
if _config_recents.empty():
|
||||
popup.add_item(translator.tr("None"), ExtraOption.RECENT)
|
||||
popup.set_item_disabled(popup.get_item_index(ExtraOption.RECENT), true)
|
||||
else:
|
||||
for i in _config_recents.size():
|
||||
@ -367,7 +359,7 @@ func _on_Extra_about_to_show():
|
||||
func _on_Extra_id_pressed(id: int) -> void:
|
||||
match id:
|
||||
ExtraOption.SAVE_AS:
|
||||
_popup_file_dialog(EditorFileDialog.FILE_MODE_SAVE_FILE, _on_SaveAsDialog_confirmed, DefaultFilename.GUESS_FOR_SAVE)
|
||||
_popup_file_dialog(EditorFileDialog.MODE_SAVE_FILE, "_on_SaveAsDialog_confirmed", DefaultFilename.GUESS_FOR_SAVE)
|
||||
|
||||
ExtraOption.COPY:
|
||||
if not _config_clipboard:
|
||||
@ -379,10 +371,10 @@ func _on_Extra_id_pressed(id: int) -> void:
|
||||
|
||||
ExtraOption.PASTE_JSFXR:
|
||||
var pasted := SFXRConfig.new()
|
||||
if pasted.load_from_base58(DisplayServer.clipboard_get()) == OK:
|
||||
if pasted.load_from_base58(OS.clipboard) == OK:
|
||||
_restore_from_config(pasted)
|
||||
else:
|
||||
_popup_message(translator.t("Clipboard does not contain code copied from jsfxr."))
|
||||
_popup_message(translator.tr("Clipboard does not contain code copied from jsfxr."))
|
||||
|
||||
_:
|
||||
var i := id - ExtraOption.RECENT as int
|
||||
|
@ -1,297 +1,394 @@
|
||||
[gd_scene load_steps=7 format=3 uid="uid://dv8q33r8aan5b"]
|
||||
[gd_scene load_steps=7 format=2]
|
||||
|
||||
[ext_resource type="Script" path="res://addons/gdfxr/editor/EditorIconButton.gd" id="1"]
|
||||
[ext_resource type="Script" path="res://addons/gdfxr/editor/Editor.gd" id="2"]
|
||||
[ext_resource type="PackedScene" uid="uid://p27e3x3kk5e0" path="res://addons/gdfxr/editor/ParamSlider.tscn" id="3"]
|
||||
[ext_resource type="PackedScene" uid="uid://b8wt6fq8w6mxc" path="res://addons/gdfxr/editor/ParamOption.tscn" id="4"]
|
||||
[ext_resource type="PackedScene" uid="uid://cewvefxbttrds" path="res://addons/gdfxr/editor/PluginTranslator.tscn" id="5"]
|
||||
[ext_resource type="PackedScene" path="res://addons/gdfxr/editor/VersionButton.tscn" id="6"]
|
||||
[ext_resource path="res://addons/gdfxr/editor/EditorIconButton.gd" type="Script" id=1]
|
||||
[ext_resource path="res://addons/gdfxr/editor/Editor.gd" type="Script" id=2]
|
||||
[ext_resource path="res://addons/gdfxr/editor/ParamSlider.tscn" type="PackedScene" id=3]
|
||||
[ext_resource path="res://addons/gdfxr/editor/ParamOption.tscn" type="PackedScene" id=4]
|
||||
[ext_resource path="res://addons/gdfxr/editor/PluginTranslator.tscn" type="PackedScene" id=5]
|
||||
[ext_resource path="res://addons/gdfxr/editor/VersionButton.tscn" type="PackedScene" id=6]
|
||||
|
||||
[node name="Editor" type="VBoxContainer"]
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("2")
|
||||
script = ExtResource( 2 )
|
||||
|
||||
[node name="AudioStreamPlayer" type="AudioStreamPlayer" parent="."]
|
||||
|
||||
[node name="Toolbar" type="HBoxContainer" parent="."]
|
||||
layout_mode = 2
|
||||
margin_right = 1024.0
|
||||
margin_bottom = 22.0
|
||||
|
||||
[node name="New" type="Button" parent="Toolbar"]
|
||||
layout_mode = 2
|
||||
tooltip_text = "New"
|
||||
flat = true
|
||||
script = ExtResource("1")
|
||||
[node name="New" type="ToolButton" parent="Toolbar"]
|
||||
margin_right = 12.0
|
||||
margin_bottom = 22.0
|
||||
hint_tooltip = "New"
|
||||
script = ExtResource( 1 )
|
||||
icon_name = "New"
|
||||
|
||||
[node name="Load" type="Button" parent="Toolbar"]
|
||||
layout_mode = 2
|
||||
tooltip_text = "Load"
|
||||
flat = true
|
||||
script = ExtResource("1")
|
||||
[node name="Load" type="ToolButton" parent="Toolbar"]
|
||||
margin_left = 16.0
|
||||
margin_right = 28.0
|
||||
margin_bottom = 22.0
|
||||
hint_tooltip = "Load"
|
||||
script = ExtResource( 1 )
|
||||
icon_name = "Load"
|
||||
|
||||
[node name="Save" type="Button" parent="Toolbar"]
|
||||
layout_mode = 2
|
||||
tooltip_text = "Save"
|
||||
flat = true
|
||||
script = ExtResource("1")
|
||||
[node name="Save" type="ToolButton" parent="Toolbar"]
|
||||
margin_left = 32.0
|
||||
margin_right = 44.0
|
||||
margin_bottom = 22.0
|
||||
hint_tooltip = "Save"
|
||||
script = ExtResource( 1 )
|
||||
icon_name = "Save"
|
||||
|
||||
[node name="Extra" type="MenuButton" parent="Toolbar"]
|
||||
layout_mode = 2
|
||||
tooltip_text = "Extra Options"
|
||||
script = ExtResource("1")
|
||||
margin_left = 48.0
|
||||
margin_right = 60.0
|
||||
margin_bottom = 22.0
|
||||
hint_tooltip = "Extra Options"
|
||||
script = ExtResource( 1 )
|
||||
icon_name = "GuiTabMenuHl"
|
||||
|
||||
[node name="VSeparator" type="VSeparator" parent="Toolbar"]
|
||||
layout_mode = 2
|
||||
margin_left = 64.0
|
||||
margin_right = 68.0
|
||||
margin_bottom = 22.0
|
||||
|
||||
[node name="Play" type="Button" parent="Toolbar"]
|
||||
layout_mode = 2
|
||||
margin_left = 72.0
|
||||
margin_right = 152.0
|
||||
margin_bottom = 22.0
|
||||
rect_min_size = Vector2( 80, 0 )
|
||||
size_flags_horizontal = 0
|
||||
text = "Play"
|
||||
script = ExtResource("1")
|
||||
script = ExtResource( 1 )
|
||||
icon_name = "Play"
|
||||
|
||||
[node name="Restore" type="Button" parent="Toolbar"]
|
||||
layout_mode = 2
|
||||
tooltip_text = "Restore"
|
||||
margin_left = 156.0
|
||||
margin_right = 236.0
|
||||
margin_bottom = 22.0
|
||||
rect_min_size = Vector2( 80, 0 )
|
||||
hint_tooltip = "Restore"
|
||||
disabled = true
|
||||
text = "Restore"
|
||||
script = ExtResource("1")
|
||||
script = ExtResource( 1 )
|
||||
icon_name = "Reload"
|
||||
|
||||
[node name="VSeparator2" type="VSeparator" parent="Toolbar"]
|
||||
layout_mode = 2
|
||||
margin_left = 240.0
|
||||
margin_right = 244.0
|
||||
margin_bottom = 22.0
|
||||
|
||||
[node name="Filename" type="Label" parent="Toolbar"]
|
||||
layout_mode = 2
|
||||
margin_left = 248.0
|
||||
margin_top = 4.0
|
||||
margin_right = 1020.0
|
||||
margin_bottom = 18.0
|
||||
size_flags_horizontal = 3
|
||||
text = "Unsaved sound"
|
||||
clip_text = true
|
||||
|
||||
[node name="VersionButton" parent="Toolbar" instance=ExtResource("6")]
|
||||
layout_mode = 2
|
||||
[node name="VersionButton" parent="Toolbar" instance=ExtResource( 6 )]
|
||||
margin_top = 4.0
|
||||
margin_bottom = 18.0
|
||||
website = "https://github.com/timothyqiu/gdfxr"
|
||||
|
||||
[node name="HSeparator" type="HSeparator" parent="."]
|
||||
layout_mode = 2
|
||||
margin_top = 26.0
|
||||
margin_right = 1024.0
|
||||
margin_bottom = 30.0
|
||||
|
||||
[node name="Editor" type="HBoxContainer" parent="."]
|
||||
layout_mode = 2
|
||||
margin_top = 34.0
|
||||
margin_right = 1024.0
|
||||
margin_bottom = 600.0
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="Generators" type="VBoxContainer" parent="Editor"]
|
||||
layout_mode = 2
|
||||
margin_right = 128.0
|
||||
margin_bottom = 566.0
|
||||
rect_min_size = Vector2( 128, 0 )
|
||||
|
||||
[node name="Button" type="Button" parent="Editor/Generators"]
|
||||
layout_mode = 2
|
||||
margin_right = 128.0
|
||||
margin_bottom = 20.0
|
||||
text = "Pickup/Coin"
|
||||
|
||||
[node name="Button2" type="Button" parent="Editor/Generators"]
|
||||
layout_mode = 2
|
||||
margin_top = 24.0
|
||||
margin_right = 128.0
|
||||
margin_bottom = 44.0
|
||||
text = "Laser/Shoot"
|
||||
|
||||
[node name="Button3" type="Button" parent="Editor/Generators"]
|
||||
layout_mode = 2
|
||||
margin_top = 48.0
|
||||
margin_right = 128.0
|
||||
margin_bottom = 68.0
|
||||
text = "Explosion"
|
||||
|
||||
[node name="Button4" type="Button" parent="Editor/Generators"]
|
||||
layout_mode = 2
|
||||
margin_top = 72.0
|
||||
margin_right = 128.0
|
||||
margin_bottom = 92.0
|
||||
text = "Powerup"
|
||||
|
||||
[node name="Button5" type="Button" parent="Editor/Generators"]
|
||||
layout_mode = 2
|
||||
margin_top = 96.0
|
||||
margin_right = 128.0
|
||||
margin_bottom = 116.0
|
||||
text = "Hit/Hurt"
|
||||
|
||||
[node name="Button6" type="Button" parent="Editor/Generators"]
|
||||
layout_mode = 2
|
||||
margin_top = 120.0
|
||||
margin_right = 128.0
|
||||
margin_bottom = 140.0
|
||||
text = "Jump"
|
||||
|
||||
[node name="Button7" type="Button" parent="Editor/Generators"]
|
||||
layout_mode = 2
|
||||
margin_top = 144.0
|
||||
margin_right = 128.0
|
||||
margin_bottom = 164.0
|
||||
text = "Blip/Select"
|
||||
|
||||
[node name="HSeparator" type="HSeparator" parent="Editor/Generators"]
|
||||
layout_mode = 2
|
||||
margin_top = 168.0
|
||||
margin_right = 128.0
|
||||
margin_bottom = 172.0
|
||||
|
||||
[node name="Button8" type="Button" parent="Editor/Generators"]
|
||||
layout_mode = 2
|
||||
margin_top = 176.0
|
||||
margin_right = 128.0
|
||||
margin_bottom = 196.0
|
||||
size_flags_horizontal = 3
|
||||
text = "Mutate"
|
||||
|
||||
[node name="Button9" type="Button" parent="Editor/Generators"]
|
||||
layout_mode = 2
|
||||
margin_top = 200.0
|
||||
margin_right = 128.0
|
||||
margin_bottom = 220.0
|
||||
size_flags_horizontal = 3
|
||||
text = "Randomize"
|
||||
|
||||
[node name="ScrollContainer" type="ScrollContainer" parent="Editor"]
|
||||
layout_mode = 2
|
||||
margin_left = 132.0
|
||||
margin_right = 1024.0
|
||||
margin_bottom = 566.0
|
||||
size_flags_horizontal = 3
|
||||
scroll_vertical_enabled = false
|
||||
|
||||
[node name="Params" type="HBoxContainer" parent="Editor/ScrollContainer"]
|
||||
layout_mode = 2
|
||||
margin_top = 188.0
|
||||
margin_right = 895.0
|
||||
margin_bottom = 366.0
|
||||
size_flags_horizontal = 6
|
||||
size_flags_vertical = 6
|
||||
|
||||
[node name="Envolope" type="VBoxContainer" parent="Editor/ScrollContainer/Params"]
|
||||
layout_mode = 2
|
||||
margin_right = 211.0
|
||||
margin_bottom = 178.0
|
||||
|
||||
[node name="ParamSlider" parent="Editor/ScrollContainer/Params/Envolope" instance=ExtResource("3")]
|
||||
layout_mode = 2
|
||||
[node name="ParamSlider" parent="Editor/ScrollContainer/Params/Envolope" instance=ExtResource( 3 )]
|
||||
margin_right = 211.0
|
||||
margin_bottom = 22.0
|
||||
label = "Attack Time"
|
||||
parameter = "p_env_attack"
|
||||
|
||||
[node name="ParamSlider2" parent="Editor/ScrollContainer/Params/Envolope" instance=ExtResource("3")]
|
||||
layout_mode = 2
|
||||
[node name="ParamSlider2" parent="Editor/ScrollContainer/Params/Envolope" instance=ExtResource( 3 )]
|
||||
margin_top = 26.0
|
||||
margin_right = 211.0
|
||||
margin_bottom = 48.0
|
||||
label = "Sustain Time"
|
||||
parameter = "p_env_sustain"
|
||||
|
||||
[node name="ParamSlider3" parent="Editor/ScrollContainer/Params/Envolope" instance=ExtResource("3")]
|
||||
layout_mode = 2
|
||||
[node name="ParamSlider3" parent="Editor/ScrollContainer/Params/Envolope" instance=ExtResource( 3 )]
|
||||
margin_top = 52.0
|
||||
margin_right = 211.0
|
||||
margin_bottom = 74.0
|
||||
label = "Sustain Punch"
|
||||
parameter = "p_env_punch"
|
||||
|
||||
[node name="ParamSlider4" parent="Editor/ScrollContainer/Params/Envolope" instance=ExtResource("3")]
|
||||
layout_mode = 2
|
||||
[node name="ParamSlider4" parent="Editor/ScrollContainer/Params/Envolope" instance=ExtResource( 3 )]
|
||||
margin_top = 78.0
|
||||
margin_right = 211.0
|
||||
margin_bottom = 100.0
|
||||
label = "Decay Time"
|
||||
parameter = "p_env_decay"
|
||||
|
||||
[node name="ParamSlider5" parent="Editor/ScrollContainer/Params/Envolope" instance=ExtResource("3")]
|
||||
layout_mode = 2
|
||||
[node name="ParamSlider5" parent="Editor/ScrollContainer/Params/Envolope" instance=ExtResource( 3 )]
|
||||
margin_top = 104.0
|
||||
margin_right = 211.0
|
||||
margin_bottom = 126.0
|
||||
label = "Change Amount"
|
||||
parameter = "p_arp_mod"
|
||||
bipolar = true
|
||||
|
||||
[node name="ParamSlider6" parent="Editor/ScrollContainer/Params/Envolope" instance=ExtResource("3")]
|
||||
layout_mode = 2
|
||||
[node name="ParamSlider6" parent="Editor/ScrollContainer/Params/Envolope" instance=ExtResource( 3 )]
|
||||
margin_top = 130.0
|
||||
margin_right = 211.0
|
||||
margin_bottom = 152.0
|
||||
label = "Change Speed"
|
||||
parameter = "p_arp_speed"
|
||||
|
||||
[node name="ParamSlider7" parent="Editor/ScrollContainer/Params/Envolope" instance=ExtResource("3")]
|
||||
layout_mode = 2
|
||||
[node name="ParamSlider7" parent="Editor/ScrollContainer/Params/Envolope" instance=ExtResource( 3 )]
|
||||
margin_top = 156.0
|
||||
margin_right = 211.0
|
||||
margin_bottom = 178.0
|
||||
label = "Volume"
|
||||
parameter = "sound_vol"
|
||||
|
||||
[node name="Frequency" type="VBoxContainer" parent="Editor/ScrollContainer/Params"]
|
||||
layout_mode = 2
|
||||
margin_left = 215.0
|
||||
margin_right = 425.0
|
||||
margin_bottom = 178.0
|
||||
|
||||
[node name="ParamSlider" parent="Editor/ScrollContainer/Params/Frequency" instance=ExtResource("3")]
|
||||
layout_mode = 2
|
||||
[node name="ParamSlider" parent="Editor/ScrollContainer/Params/Frequency" instance=ExtResource( 3 )]
|
||||
margin_right = 210.0
|
||||
margin_bottom = 22.0
|
||||
label = "Start Frequency"
|
||||
parameter = "p_base_freq"
|
||||
|
||||
[node name="ParamSlider2" parent="Editor/ScrollContainer/Params/Frequency" instance=ExtResource("3")]
|
||||
layout_mode = 2
|
||||
[node name="ParamSlider2" parent="Editor/ScrollContainer/Params/Frequency" instance=ExtResource( 3 )]
|
||||
margin_top = 26.0
|
||||
margin_right = 210.0
|
||||
margin_bottom = 48.0
|
||||
label = "Min Frequency"
|
||||
parameter = "p_freq_limit"
|
||||
|
||||
[node name="ParamSlider3" parent="Editor/ScrollContainer/Params/Frequency" instance=ExtResource("3")]
|
||||
layout_mode = 2
|
||||
[node name="ParamSlider3" parent="Editor/ScrollContainer/Params/Frequency" instance=ExtResource( 3 )]
|
||||
margin_top = 52.0
|
||||
margin_right = 210.0
|
||||
margin_bottom = 74.0
|
||||
label = "Slide"
|
||||
parameter = "p_freq_ramp"
|
||||
bipolar = true
|
||||
|
||||
[node name="ParamSlider4" parent="Editor/ScrollContainer/Params/Frequency" instance=ExtResource("3")]
|
||||
layout_mode = 2
|
||||
[node name="ParamSlider4" parent="Editor/ScrollContainer/Params/Frequency" instance=ExtResource( 3 )]
|
||||
margin_top = 78.0
|
||||
margin_right = 210.0
|
||||
margin_bottom = 100.0
|
||||
label = "Delta Slide"
|
||||
parameter = "p_freq_dramp"
|
||||
bipolar = true
|
||||
|
||||
[node name="ParamSlider5" parent="Editor/ScrollContainer/Params/Frequency" instance=ExtResource("3")]
|
||||
layout_mode = 2
|
||||
[node name="ParamSlider5" parent="Editor/ScrollContainer/Params/Frequency" instance=ExtResource( 3 )]
|
||||
margin_top = 104.0
|
||||
margin_right = 210.0
|
||||
margin_bottom = 126.0
|
||||
label = "Vibrato Depth"
|
||||
parameter = "p_vib_strength"
|
||||
|
||||
[node name="ParamSlider6" parent="Editor/ScrollContainer/Params/Frequency" instance=ExtResource("3")]
|
||||
layout_mode = 2
|
||||
[node name="ParamSlider6" parent="Editor/ScrollContainer/Params/Frequency" instance=ExtResource( 3 )]
|
||||
margin_top = 130.0
|
||||
margin_right = 210.0
|
||||
margin_bottom = 152.0
|
||||
label = "Vibrato Speed"
|
||||
parameter = "p_vib_speed"
|
||||
|
||||
[node name="ParamSlider7" parent="Editor/ScrollContainer/Params/Frequency" instance=ExtResource("3")]
|
||||
layout_mode = 2
|
||||
[node name="ParamSlider7" parent="Editor/ScrollContainer/Params/Frequency" instance=ExtResource( 3 )]
|
||||
margin_top = 156.0
|
||||
margin_right = 210.0
|
||||
margin_bottom = 178.0
|
||||
label = "Repeat Speed"
|
||||
parameter = "p_repeat_speed"
|
||||
|
||||
[node name="Waveform" type="VBoxContainer" parent="Editor/ScrollContainer/Params"]
|
||||
layout_mode = 2
|
||||
margin_left = 429.0
|
||||
margin_right = 649.0
|
||||
margin_bottom = 178.0
|
||||
|
||||
[node name="WaveformOption" parent="Editor/ScrollContainer/Params/Waveform" instance=ExtResource("4")]
|
||||
layout_mode = 2
|
||||
options = ["Square", "Sawtooth", "Sine", "Noise"]
|
||||
[node name="WaveformOption" parent="Editor/ScrollContainer/Params/Waveform" instance=ExtResource( 4 )]
|
||||
margin_right = 220.0
|
||||
margin_bottom = 22.0
|
||||
options = [ "Square", "Sawtooth", "Sine", "Noise" ]
|
||||
parameter = "wave_type"
|
||||
|
||||
[node name="ParamSlider" parent="Editor/ScrollContainer/Params/Waveform" instance=ExtResource("3")]
|
||||
layout_mode = 2
|
||||
[node name="ParamSlider" parent="Editor/ScrollContainer/Params/Waveform" instance=ExtResource( 3 )]
|
||||
margin_top = 26.0
|
||||
margin_right = 220.0
|
||||
margin_bottom = 48.0
|
||||
label = "Square Duty"
|
||||
parameter = "p_duty"
|
||||
|
||||
[node name="ParamSlider2" parent="Editor/ScrollContainer/Params/Waveform" instance=ExtResource("3")]
|
||||
layout_mode = 2
|
||||
[node name="ParamSlider2" parent="Editor/ScrollContainer/Params/Waveform" instance=ExtResource( 3 )]
|
||||
margin_top = 52.0
|
||||
margin_right = 220.0
|
||||
margin_bottom = 74.0
|
||||
label = "Duty Sweep"
|
||||
parameter = "p_duty_ramp"
|
||||
bipolar = true
|
||||
|
||||
[node name="ParamSlider5" parent="Editor/ScrollContainer/Params/Waveform" instance=ExtResource("3")]
|
||||
layout_mode = 2
|
||||
[node name="ParamSlider5" parent="Editor/ScrollContainer/Params/Waveform" instance=ExtResource( 3 )]
|
||||
margin_top = 78.0
|
||||
margin_right = 220.0
|
||||
margin_bottom = 100.0
|
||||
label = "Phaser Offset"
|
||||
parameter = "p_pha_offset"
|
||||
bipolar = true
|
||||
|
||||
[node name="ParamSlider3" parent="Editor/ScrollContainer/Params/Waveform" instance=ExtResource("3")]
|
||||
layout_mode = 2
|
||||
[node name="ParamSlider3" parent="Editor/ScrollContainer/Params/Waveform" instance=ExtResource( 3 )]
|
||||
margin_top = 104.0
|
||||
margin_right = 220.0
|
||||
margin_bottom = 126.0
|
||||
label = "Phaser Sweep"
|
||||
parameter = "p_pha_ramp"
|
||||
bipolar = true
|
||||
|
||||
[node name="Filter" type="VBoxContainer" parent="Editor/ScrollContainer/Params"]
|
||||
layout_mode = 2
|
||||
margin_left = 653.0
|
||||
margin_right = 895.0
|
||||
margin_bottom = 178.0
|
||||
|
||||
[node name="ParamSlider" parent="Editor/ScrollContainer/Params/Filter" instance=ExtResource("3")]
|
||||
layout_mode = 2
|
||||
[node name="ParamSlider" parent="Editor/ScrollContainer/Params/Filter" instance=ExtResource( 3 )]
|
||||
margin_right = 242.0
|
||||
margin_bottom = 22.0
|
||||
label = "Low-pass Cutoff"
|
||||
parameter = "p_lpf_freq"
|
||||
|
||||
[node name="ParamSlider2" parent="Editor/ScrollContainer/Params/Filter" instance=ExtResource("3")]
|
||||
layout_mode = 2
|
||||
[node name="ParamSlider2" parent="Editor/ScrollContainer/Params/Filter" instance=ExtResource( 3 )]
|
||||
margin_top = 26.0
|
||||
margin_right = 242.0
|
||||
margin_bottom = 48.0
|
||||
label = "Low-pass Sweep"
|
||||
parameter = "p_lpf_ramp"
|
||||
bipolar = true
|
||||
|
||||
[node name="ParamSlider5" parent="Editor/ScrollContainer/Params/Filter" instance=ExtResource("3")]
|
||||
layout_mode = 2
|
||||
[node name="ParamSlider5" parent="Editor/ScrollContainer/Params/Filter" instance=ExtResource( 3 )]
|
||||
margin_top = 52.0
|
||||
margin_right = 242.0
|
||||
margin_bottom = 74.0
|
||||
label = "Low-pass Resonance"
|
||||
parameter = "p_lpf_resonance"
|
||||
|
||||
[node name="ParamSlider3" parent="Editor/ScrollContainer/Params/Filter" instance=ExtResource("3")]
|
||||
layout_mode = 2
|
||||
[node name="ParamSlider3" parent="Editor/ScrollContainer/Params/Filter" instance=ExtResource( 3 )]
|
||||
margin_top = 78.0
|
||||
margin_right = 242.0
|
||||
margin_bottom = 100.0
|
||||
label = "High-pass Cutoff"
|
||||
parameter = "p_hpf_freq"
|
||||
|
||||
[node name="ParamSlider4" parent="Editor/ScrollContainer/Params/Filter" instance=ExtResource("3")]
|
||||
layout_mode = 2
|
||||
[node name="ParamSlider4" parent="Editor/ScrollContainer/Params/Filter" instance=ExtResource( 3 )]
|
||||
margin_top = 104.0
|
||||
margin_right = 242.0
|
||||
margin_bottom = 126.0
|
||||
label = "High-pass Sweep"
|
||||
parameter = "p_hpf_ramp"
|
||||
bipolar = true
|
||||
|
||||
[node name="PluginTranslator" parent="." instance=ExtResource("5")]
|
||||
[node name="PluginTranslator" parent="." instance=ExtResource( 5 )]
|
||||
|
||||
[connection signal="pressed" from="Toolbar/New" to="." method="_on_New_pressed"]
|
||||
[connection signal="pressed" from="Toolbar/Load" to="." method="_on_Load_pressed"]
|
||||
[connection signal="pressed" from="Toolbar/Save" to="." method="_on_Save_pressed"]
|
||||
[connection signal="about_to_popup" from="Toolbar/Extra" to="." method="_on_Extra_about_to_show"]
|
||||
[connection signal="about_to_show" from="Toolbar/Extra" to="." method="_on_Extra_about_to_show"]
|
||||
[connection signal="pressed" from="Toolbar/Play" to="." method="_on_Play_pressed"]
|
||||
[connection signal="pressed" from="Toolbar/Restore" to="." method="_on_Restore_pressed"]
|
||||
[connection signal="pressed" from="Editor/Generators/Button" to="." method="_on_Randomize_pressed" binds= [0]]
|
||||
[connection signal="pressed" from="Editor/Generators/Button2" to="." method="_on_Randomize_pressed" binds= [1]]
|
||||
[connection signal="pressed" from="Editor/Generators/Button3" to="." method="_on_Randomize_pressed" binds= [2]]
|
||||
[connection signal="pressed" from="Editor/Generators/Button4" to="." method="_on_Randomize_pressed" binds= [3]]
|
||||
[connection signal="pressed" from="Editor/Generators/Button5" to="." method="_on_Randomize_pressed" binds= [4]]
|
||||
[connection signal="pressed" from="Editor/Generators/Button6" to="." method="_on_Randomize_pressed" binds= [5]]
|
||||
[connection signal="pressed" from="Editor/Generators/Button7" to="." method="_on_Randomize_pressed" binds= [6]]
|
||||
[connection signal="pressed" from="Editor/Generators/Button" to="." method="_on_Randomize_pressed" binds= [ 0 ]]
|
||||
[connection signal="pressed" from="Editor/Generators/Button2" to="." method="_on_Randomize_pressed" binds= [ 1 ]]
|
||||
[connection signal="pressed" from="Editor/Generators/Button3" to="." method="_on_Randomize_pressed" binds= [ 2 ]]
|
||||
[connection signal="pressed" from="Editor/Generators/Button4" to="." method="_on_Randomize_pressed" binds= [ 3 ]]
|
||||
[connection signal="pressed" from="Editor/Generators/Button5" to="." method="_on_Randomize_pressed" binds= [ 4 ]]
|
||||
[connection signal="pressed" from="Editor/Generators/Button6" to="." method="_on_Randomize_pressed" binds= [ 5 ]]
|
||||
[connection signal="pressed" from="Editor/Generators/Button7" to="." method="_on_Randomize_pressed" binds= [ 6 ]]
|
||||
[connection signal="pressed" from="Editor/Generators/Button8" to="." method="_on_Mutate_pressed"]
|
||||
[connection signal="pressed" from="Editor/Generators/Button9" to="." method="_on_Randomize_pressed" binds= [-1]]
|
||||
[connection signal="pressed" from="Editor/Generators/Button9" to="." method="_on_Randomize_pressed" binds= [ -1 ]]
|
||||
|
@ -1,7 +1,7 @@
|
||||
@tool
|
||||
tool
|
||||
extends Button
|
||||
|
||||
@export var icon_name: String
|
||||
export var icon_name: String
|
||||
|
||||
var plugin: EditorPlugin # a hack to know if this is executing as plugin
|
||||
|
||||
|
@ -1,14 +1,13 @@
|
||||
@tool
|
||||
tool
|
||||
extends HBoxContainer
|
||||
|
||||
signal param_changed(name, value)
|
||||
signal param_reset(name)
|
||||
|
||||
@export var options: Array :
|
||||
set = set_options
|
||||
@export var parameter: String # Could be PackedStringArray, but pybabel won't catch that
|
||||
export var options: Array setget set_options
|
||||
export var parameter: String # Could be PoolStringArray, but pybabel won't catch that
|
||||
|
||||
@onready var option_button := $OptionButton as OptionButton
|
||||
onready var option_button := $OptionButton as OptionButton
|
||||
|
||||
|
||||
func _ready():
|
||||
|
@ -1,34 +1,42 @@
|
||||
[gd_scene load_steps=3 format=3 uid="uid://b8wt6fq8w6mxc"]
|
||||
[gd_scene load_steps=3 format=2]
|
||||
|
||||
[ext_resource type="Script" path="res://addons/gdfxr/editor/ParamOption.gd" id="1"]
|
||||
[ext_resource type="Script" path="res://addons/gdfxr/editor/EditorIconButton.gd" id="2"]
|
||||
[ext_resource path="res://addons/gdfxr/editor/ParamOption.gd" type="Script" id=1]
|
||||
[ext_resource path="res://addons/gdfxr/editor/EditorIconButton.gd" type="Script" id=2]
|
||||
|
||||
[node name="WaveformOption" type="HBoxContainer"]
|
||||
offset_right = 253.0
|
||||
offset_bottom = 40.0
|
||||
pivot_offset = Vector2(41, -65)
|
||||
margin_right = 253.0
|
||||
margin_bottom = 40.0
|
||||
rect_pivot_offset = Vector2( 41, -65 )
|
||||
size_flags_horizontal = 3
|
||||
script = ExtResource("1")
|
||||
script = ExtResource( 1 )
|
||||
|
||||
[node name="Label" type="Label" parent="."]
|
||||
custom_minimum_size = Vector2(100, 0)
|
||||
layout_mode = 2
|
||||
margin_top = 13.0
|
||||
margin_right = 128.0
|
||||
margin_bottom = 27.0
|
||||
rect_min_size = Vector2( 100, 0 )
|
||||
size_flags_horizontal = 3
|
||||
text = "Waveform"
|
||||
horizontal_alignment = 2
|
||||
align = 2
|
||||
|
||||
[node name="OptionButton" type="OptionButton" parent="."]
|
||||
custom_minimum_size = Vector2(105, 0)
|
||||
layout_mode = 2
|
||||
margin_left = 132.0
|
||||
margin_top = 10.0
|
||||
margin_right = 237.0
|
||||
margin_bottom = 30.0
|
||||
rect_min_size = Vector2( 105, 0 )
|
||||
size_flags_vertical = 4
|
||||
clip_text = true
|
||||
|
||||
[node name="Reset" type="Button" parent="."]
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 4
|
||||
[node name="Reset" type="ToolButton" parent="."]
|
||||
margin_left = 241.0
|
||||
margin_top = 9.0
|
||||
margin_right = 253.0
|
||||
margin_bottom = 31.0
|
||||
focus_mode = 0
|
||||
flat = true
|
||||
script = ExtResource("2")
|
||||
size_flags_vertical = 4
|
||||
enabled_focus_mode = 0
|
||||
script = ExtResource( 2 )
|
||||
icon_name = "ReloadSmall"
|
||||
|
||||
[connection signal="item_selected" from="OptionButton" to="." method="_on_OptionButton_item_selected"]
|
||||
|
@ -1,33 +1,21 @@
|
||||
@tool
|
||||
tool
|
||||
extends HBoxContainer
|
||||
|
||||
signal param_changed(name, value)
|
||||
signal param_reset(name)
|
||||
|
||||
@export var label: String :
|
||||
set = set_label
|
||||
@export var parameter: String
|
||||
@export var bipolar := false :
|
||||
set = set_bipolar
|
||||
|
||||
|
||||
func _ready():
|
||||
set_label(label)
|
||||
set_bipolar(bipolar)
|
||||
export var label: String setget set_label
|
||||
export var parameter: String
|
||||
export var bipolar := false setget set_bipolar
|
||||
|
||||
|
||||
func set_label(v: String) -> void:
|
||||
label = v
|
||||
if is_inside_tree():
|
||||
$Label.text = v
|
||||
|
||||
|
||||
func set_bipolar(v: bool) -> void:
|
||||
bipolar = v
|
||||
|
||||
if not is_inside_tree():
|
||||
return
|
||||
|
||||
if bipolar:
|
||||
$HSlider.min_value = -1.0
|
||||
else:
|
||||
|
@ -1,35 +1,41 @@
|
||||
[gd_scene load_steps=4 format=3 uid="uid://p27e3x3kk5e0"]
|
||||
[gd_scene load_steps=4 format=2]
|
||||
|
||||
[ext_resource type="Script" path="res://addons/gdfxr/editor/ParamSlider.gd" id="1"]
|
||||
[ext_resource type="Script" path="res://addons/gdfxr/editor/EditorIconButton.gd" id="2"]
|
||||
[ext_resource type="Script" path="res://addons/gdfxr/editor/EditSlider.gd" id="3"]
|
||||
[ext_resource path="res://addons/gdfxr/editor/ParamSlider.gd" type="Script" id=1]
|
||||
[ext_resource path="res://addons/gdfxr/editor/EditorIconButton.gd" type="Script" id=2]
|
||||
[ext_resource path="res://addons/gdfxr/editor/EditSlider.gd" type="Script" id=3]
|
||||
|
||||
[node name="ParamSlider" type="HBoxContainer"]
|
||||
offset_right = 253.0
|
||||
offset_bottom = 40.0
|
||||
margin_right = 253.0
|
||||
margin_bottom = 40.0
|
||||
size_flags_horizontal = 3
|
||||
script = ExtResource("1")
|
||||
script = ExtResource( 1 )
|
||||
|
||||
[node name="Label" type="Label" parent="."]
|
||||
custom_minimum_size = Vector2(100, 0)
|
||||
layout_mode = 2
|
||||
margin_top = 13.0
|
||||
margin_right = 128.0
|
||||
margin_bottom = 27.0
|
||||
rect_min_size = Vector2( 100, 0 )
|
||||
size_flags_horizontal = 3
|
||||
horizontal_alignment = 2
|
||||
align = 2
|
||||
|
||||
[node name="HSlider" type="Control" parent="."]
|
||||
clip_contents = true
|
||||
custom_minimum_size = Vector2(105, 0)
|
||||
layout_mode = 2
|
||||
margin_left = 132.0
|
||||
margin_right = 237.0
|
||||
margin_bottom = 40.0
|
||||
rect_min_size = Vector2( 105, 0 )
|
||||
rect_clip_content = true
|
||||
focus_mode = 2
|
||||
mouse_default_cursor_shape = 10
|
||||
script = ExtResource("3")
|
||||
script = ExtResource( 3 )
|
||||
|
||||
[node name="Reset" type="Button" parent="."]
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 4
|
||||
[node name="Reset" type="ToolButton" parent="."]
|
||||
margin_left = 241.0
|
||||
margin_top = 9.0
|
||||
margin_right = 253.0
|
||||
margin_bottom = 31.0
|
||||
focus_mode = 0
|
||||
flat = true
|
||||
script = ExtResource("2")
|
||||
size_flags_vertical = 4
|
||||
script = ExtResource( 2 )
|
||||
icon_name = "ReloadSmall"
|
||||
|
||||
[connection signal="value_changed" from="HSlider" to="." method="_on_HSlider_value_changed"]
|
||||
|
@ -1,8 +1,7 @@
|
||||
@tool
|
||||
tool
|
||||
extends Node
|
||||
|
||||
var plugin: EditorPlugin :
|
||||
set = set_plugin
|
||||
var plugin: EditorPlugin setget set_plugin
|
||||
|
||||
var _translation: Translation
|
||||
|
||||
@ -18,40 +17,40 @@ func set_plugin(v: EditorPlugin) -> void:
|
||||
plugin = v
|
||||
var locale: String = plugin.get_editor_interface().get_editor_settings().get('interface/editor/editor_language')
|
||||
var script := get_script() as Script
|
||||
var path := script.resource_path.get_base_dir().path_join("translations/%s.po" % locale)
|
||||
var path := script.resource_path.get_base_dir().plus_file("translations/%s.po" % locale)
|
||||
if ResourceLoader.exists(path):
|
||||
_translation = ResourceLoader.load(path)
|
||||
|
||||
if _translation:
|
||||
_translate_node.call_deferred(get_parent())
|
||||
_translate_node(get_parent())
|
||||
|
||||
|
||||
func t(message: StringName) -> String:
|
||||
func tr(message: StringName) -> StringName:
|
||||
if _translation:
|
||||
var translated := _translation.get_message(message)
|
||||
if translated:
|
||||
return String(translated)
|
||||
return String(message)
|
||||
if translated != "":
|
||||
return translated
|
||||
return message
|
||||
|
||||
|
||||
func _translate_node(node: Node):
|
||||
if node is Control:
|
||||
node.tooltip_text = t(node.tooltip_text)
|
||||
node.hint_tooltip = tr(node.hint_tooltip)
|
||||
|
||||
if node is HBoxContainer and node.has_method("set_options"):
|
||||
var options = []
|
||||
for item in node.options:
|
||||
options.append(t(item))
|
||||
options.append(tr(item))
|
||||
node.options = options
|
||||
|
||||
if node is Button and not node is OptionButton:
|
||||
node.text = t(node.text)
|
||||
node.text = tr(node.text)
|
||||
|
||||
if node is Label:
|
||||
node.text = t(node.text)
|
||||
node.text = tr(node.text)
|
||||
|
||||
if node is Slider:
|
||||
node.tooltip_text = t(node.tooltip_text)
|
||||
node.hint_tooltip = tr(node.hint_tooltip)
|
||||
|
||||
for child in node.get_children():
|
||||
_translate_node(child)
|
||||
|
@ -1,6 +1,6 @@
|
||||
[gd_scene load_steps=2 format=3 uid="uid://cewvefxbttrds"]
|
||||
[gd_scene load_steps=2 format=2]
|
||||
|
||||
[ext_resource type="Script" path="res://addons/gdfxr/editor/PluginTranslator.gd" id="1"]
|
||||
[ext_resource path="res://addons/gdfxr/editor/PluginTranslator.gd" type="Script" id=1]
|
||||
|
||||
[node name="PluginTranslator" type="Node"]
|
||||
script = ExtResource("1")
|
||||
script = ExtResource( 1 )
|
||||
|
@ -1,17 +1,16 @@
|
||||
@tool
|
||||
tool
|
||||
extends LinkButton
|
||||
|
||||
@export var website: String
|
||||
export var website: String
|
||||
|
||||
var plugin: EditorPlugin :
|
||||
set = set_plugin
|
||||
var plugin: EditorPlugin setget set_plugin
|
||||
|
||||
|
||||
func set_plugin(v: EditorPlugin) -> void:
|
||||
plugin = v
|
||||
|
||||
var script := get_script() as Script
|
||||
var path := script.resource_path.get_base_dir().path_join("../plugin.cfg")
|
||||
var path := script.resource_path.get_base_dir().plus_file("../plugin.cfg")
|
||||
|
||||
var cfg := ConfigFile.new()
|
||||
var err := cfg.load(path)
|
||||
|
@ -4,10 +4,10 @@
|
||||
|
||||
[node name="VersionButton" type="LinkButton"]
|
||||
self_modulate = Color( 1, 1, 1, 0.65 )
|
||||
offset_left = 1024.0
|
||||
offset_top = 5.0
|
||||
offset_right = 1024.0
|
||||
offset_bottom = 19.0
|
||||
margin_left = 1024.0
|
||||
margin_top = 5.0
|
||||
margin_right = 1024.0
|
||||
margin_bottom = 19.0
|
||||
focus_mode = 2
|
||||
size_flags_vertical = 4
|
||||
underline = 1
|
||||
|
@ -1,72 +1,64 @@
|
||||
@tool
|
||||
tool
|
||||
extends EditorImportPlugin
|
||||
|
||||
const SFXRConfig = preload("SFXRConfig.gd")
|
||||
const SFXRGenerator = preload("SFXRGenerator.gd")
|
||||
|
||||
|
||||
func _get_importer_name():
|
||||
func get_importer_name():
|
||||
return "com.timothyqiu.gdfxr.importer"
|
||||
|
||||
|
||||
func _get_import_order():
|
||||
return ResourceImporter.IMPORT_ORDER_DEFAULT
|
||||
|
||||
|
||||
func _get_priority():
|
||||
return 1.0
|
||||
|
||||
|
||||
func _get_visible_name():
|
||||
func get_visible_name():
|
||||
return "SFXR Audio"
|
||||
|
||||
|
||||
func _get_recognized_extensions():
|
||||
func get_recognized_extensions():
|
||||
return ["sfxr"]
|
||||
|
||||
|
||||
func _get_save_extension():
|
||||
func get_save_extension():
|
||||
return "sample"
|
||||
|
||||
|
||||
func _get_resource_type():
|
||||
return "AudioStreamWAV"
|
||||
func get_resource_type():
|
||||
return "AudioStreamSample"
|
||||
|
||||
|
||||
func _get_preset_count():
|
||||
func get_preset_count():
|
||||
return 1
|
||||
|
||||
|
||||
func _get_preset_name(preset):
|
||||
func get_preset_name(preset):
|
||||
return "Default"
|
||||
|
||||
|
||||
func _get_import_options(path, preset):
|
||||
func get_import_options(preset):
|
||||
return [
|
||||
{
|
||||
name="loop",
|
||||
default_value=false,
|
||||
"name":"loop",
|
||||
"default_value":false,
|
||||
},
|
||||
{
|
||||
name="bit_depth",
|
||||
property_hint=PROPERTY_HINT_ENUM,
|
||||
hint_string="8 Bits,16 Bits",
|
||||
default_value=SFXRGenerator.WavBits.WAV_BITS_8,
|
||||
"name":"bit_depth",
|
||||
"property_hint":PROPERTY_HINT_ENUM,
|
||||
"hint_string":"8 Bits,16 Bits",
|
||||
"default_value":SFXRGenerator.WavBits.WAV_BITS_8,
|
||||
},
|
||||
{
|
||||
name="sample_rate",
|
||||
property_hint=PROPERTY_HINT_ENUM,
|
||||
hint_string="44100 Hz,22050 Hz",
|
||||
default_value=SFXRGenerator.WavFreq.WAV_FREQ_44100,
|
||||
"name":"sample_rate",
|
||||
"property_hint":PROPERTY_HINT_ENUM,
|
||||
"hint_string":"44100 Hz,22050 Hz",
|
||||
"default_value":SFXRGenerator.WavFreq.WAV_FREQ_44100,
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
func _get_option_visibility(path, option, options):
|
||||
func get_option_visibility(option, options):
|
||||
return true
|
||||
|
||||
|
||||
func _import(source_file, save_path, options, platform_variants, gen_files):
|
||||
func import(source_file, save_path, options, platform_variants, gen_files):
|
||||
var config := SFXRConfig.new()
|
||||
var err := config.load(source_file)
|
||||
if err != OK:
|
||||
@ -77,8 +69,8 @@ func _import(source_file, save_path, options, platform_variants, gen_files):
|
||||
config, options.bit_depth, options.sample_rate
|
||||
)
|
||||
if options.loop:
|
||||
stream.loop_mode = AudioStreamWAV.LOOP_FORWARD
|
||||
stream.loop_mode = AudioStreamSample.LOOP_FORWARD
|
||||
stream.loop_end = stream.data.size()
|
||||
|
||||
var filename = save_path + "." + _get_save_extension()
|
||||
return ResourceSaver.save(stream, filename)
|
||||
var filename = save_path + "." + get_save_extension()
|
||||
return ResourceSaver.save(filename, stream)
|
||||
|
@ -3,5 +3,5 @@
|
||||
name="gdfxr"
|
||||
description="A Godot plugin that ports sfxr, the popular program of choice to make retro sound effects for games."
|
||||
author="Haoyu Qiu"
|
||||
version="2.0"
|
||||
version="1.3"
|
||||
script="plugin.gd"
|
||||
|
@ -1,4 +1,4 @@
|
||||
@tool
|
||||
tool
|
||||
extends EditorPlugin
|
||||
|
||||
|
||||
@ -10,7 +10,7 @@ func _enter_tree():
|
||||
import_plugin = preload("import_plugin.gd").new()
|
||||
add_import_plugin(import_plugin)
|
||||
|
||||
sfxr_editor = preload("editor/Editor.tscn").instantiate()
|
||||
sfxr_editor = preload("editor/Editor.tscn").instance()
|
||||
sfxr_editor.plugin = self
|
||||
add_control_to_bottom_panel(sfxr_editor, "gdfxr")
|
||||
|
||||
@ -24,15 +24,15 @@ func _exit_tree():
|
||||
import_plugin = null
|
||||
|
||||
|
||||
func _handles(object: Object) -> bool:
|
||||
return object is AudioStreamWAV and object.resource_path.ends_with(".sfxr")
|
||||
func handles(object: Object) -> bool:
|
||||
return object is AudioStreamSample and object.resource_path.ends_with(".sfxr")
|
||||
|
||||
|
||||
func _edit(object: Object):
|
||||
sfxr_editor.edit(object)
|
||||
func edit(object: Object):
|
||||
sfxr_editor.edit(object.resource_path) # Should already passed `handles()` checks
|
||||
|
||||
|
||||
func _make_visible(visible: bool):
|
||||
func make_visible(visible: bool):
|
||||
if visible:
|
||||
make_bottom_panel_item_visible(sfxr_editor)
|
||||
elif sfxr_editor.is_visible_in_tree():
|
||||
|
@ -4,8 +4,8 @@ extends Container
|
||||
const SFXRConfig = preload("res://addons/gdfxr/SFXRConfig.gd")
|
||||
const SFXRGenerator = preload("res://addons/gdfxr/SFXRGenerator.gd")
|
||||
|
||||
@onready var audio_player: AudioStreamPlayer = $AudioPlayer
|
||||
@onready var adhoc_audio_player: AudioStreamPlayer = $AdhocAudioPlayer
|
||||
onready var audio_player: AudioStreamPlayer = $AudioPlayer
|
||||
onready var adhoc_audio_player: AudioStreamPlayer = $AdhocAudioPlayer
|
||||
|
||||
|
||||
func _on_Play_pressed() -> void:
|
||||
|
@ -1,58 +1,73 @@
|
||||
[gd_scene load_steps=3 format=3 uid="uid://bv31mn2hs6wom"]
|
||||
[gd_scene load_steps=3 format=2]
|
||||
|
||||
[ext_resource type="Script" path="res://example/Example.gd" id="1"]
|
||||
[ext_resource type="AudioStream" uid="uid://byf7u7a25fuf4" path="res://example/example.sfxr" id="2"]
|
||||
[ext_resource path="res://example/Example.gd" type="Script" id=1]
|
||||
[ext_resource path="res://example/example.sfxr" type="AudioStream" id=2]
|
||||
|
||||
[node name="Example" type="GridContainer"]
|
||||
anchors_preset = 8
|
||||
anchor_left = 0.5
|
||||
anchor_top = 0.5
|
||||
anchor_right = 0.5
|
||||
anchor_bottom = 0.5
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
theme_override_constants/h_separation = 32
|
||||
theme_override_constants/v_separation = 32
|
||||
custom_constants/hseparation = 32
|
||||
custom_constants/vseparation = 32
|
||||
columns = 2
|
||||
script = ExtResource("1")
|
||||
script = ExtResource( 1 )
|
||||
|
||||
[node name="AudioPlayer" type="AudioStreamPlayer" parent="."]
|
||||
stream = ExtResource("2")
|
||||
stream = ExtResource( 2 )
|
||||
|
||||
[node name="AdhocAudioPlayer" type="AudioStreamPlayer" parent="."]
|
||||
|
||||
[node name="Play" type="Button" parent="."]
|
||||
layout_mode = 2
|
||||
margin_right = 141.0
|
||||
margin_bottom = 32.0
|
||||
rect_min_size = Vector2( 128, 32 )
|
||||
size_flags_vertical = 4
|
||||
text = "Play"
|
||||
|
||||
[node name="Label" type="Label" parent="."]
|
||||
custom_minimum_size = Vector2(500, 0)
|
||||
layout_mode = 2
|
||||
margin_left = 173.0
|
||||
margin_right = 473.0
|
||||
margin_bottom = 31.0
|
||||
rect_min_size = Vector2( 300, 0 )
|
||||
text = "A .sfxr file can be used as regular audio files like .wav, .ogg, and .mp3."
|
||||
autowrap_mode = 3
|
||||
autowrap = true
|
||||
|
||||
[node name="PlayFile" type="Button" parent="."]
|
||||
layout_mode = 2
|
||||
margin_top = 64.0
|
||||
margin_right = 141.0
|
||||
margin_bottom = 96.0
|
||||
rect_min_size = Vector2( 128, 32 )
|
||||
size_flags_vertical = 4
|
||||
text = "Load .sfxr File"
|
||||
|
||||
[node name="Label2" type="Label" parent="."]
|
||||
custom_minimum_size = Vector2(500, 0)
|
||||
layout_mode = 2
|
||||
margin_left = 173.0
|
||||
margin_top = 64.0
|
||||
margin_right = 473.0
|
||||
margin_bottom = 95.0
|
||||
rect_min_size = Vector2( 300, 0 )
|
||||
text = "A .sfxr file is a AudioStreamSample resource that can be loaded with load() or preload()."
|
||||
autowrap_mode = 3
|
||||
autowrap = true
|
||||
|
||||
[node name="Generate" type="Button" parent="."]
|
||||
layout_mode = 2
|
||||
margin_top = 144.0
|
||||
margin_right = 141.0
|
||||
margin_bottom = 176.0
|
||||
rect_min_size = Vector2( 128, 32 )
|
||||
size_flags_vertical = 4
|
||||
text = "Runtime Generation"
|
||||
|
||||
[node name="Label3" type="Label" parent="."]
|
||||
custom_minimum_size = Vector2(500, 0)
|
||||
layout_mode = 2
|
||||
margin_left = 173.0
|
||||
margin_top = 128.0
|
||||
margin_right = 473.0
|
||||
margin_bottom = 193.0
|
||||
rect_min_size = Vector2( 300, 0 )
|
||||
text = "You can generate the sound effect at runtime. However, due to performance constraints with GDScript, your game might freeze when generating long sounds."
|
||||
autowrap_mode = 3
|
||||
autowrap = true
|
||||
|
||||
[connection signal="pressed" from="Play" to="." method="_on_Play_pressed"]
|
||||
[connection signal="pressed" from="PlayFile" to="." method="_on_PlayFile_pressed"]
|
||||
|
@ -1,14 +1,13 @@
|
||||
[remap]
|
||||
|
||||
importer="com.timothyqiu.gdfxr.importer"
|
||||
type="AudioStreamWAV"
|
||||
uid="uid://byf7u7a25fuf4"
|
||||
path="res://.godot/imported/example.sfxr-e3731bcdcd8403a2391e92667a5d1076.sample"
|
||||
type="AudioStreamSample"
|
||||
path="res://.import/example.sfxr-e3731bcdcd8403a2391e92667a5d1076.sample"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://example/example.sfxr"
|
||||
dest_files=["res://.godot/imported/example.sfxr-e3731bcdcd8403a2391e92667a5d1076.sample"]
|
||||
dest_files=[ "res://.import/example.sfxr-e3731bcdcd8403a2391e92667a5d1076.sample" ]
|
||||
|
||||
[params]
|
||||
|
||||
|
@ -1,9 +1,8 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://b16qnfl6slyy2"
|
||||
path="res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ctex"
|
||||
type="StreamTexture"
|
||||
path="res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
@ -11,24 +10,26 @@ metadata={
|
||||
[deps]
|
||||
|
||||
source_file="res://icon.png"
|
||||
dest_files=["res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ctex"]
|
||||
dest_files=[ "res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
flags/repeat=0
|
||||
flags/filter=true
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=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
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
||||
|
@ -6,15 +6,14 @@
|
||||
; [section] ; section goes between []
|
||||
; param=value ; assign values to parameters
|
||||
|
||||
config_version=5
|
||||
config_version=4
|
||||
|
||||
[application]
|
||||
|
||||
config/name="gdfxr"
|
||||
run/main_scene="res://example/Example.tscn"
|
||||
config/features=PackedStringArray("4.0")
|
||||
config/icon="res://icon.png"
|
||||
|
||||
[editor_plugins]
|
||||
|
||||
enabled=PackedStringArray("res://addons/gdfxr/plugin.cfg")
|
||||
enabled=PoolStringArray( "res://addons/gdfxr/plugin.cfg" )
|
Binary file not shown.
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 21 KiB |
Binary file not shown.
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 19 KiB |
Loading…
Reference in New Issue
Block a user