Skip to content

Commit 2892d65

Browse files
committed
Add CTL Support
1 parent 92f0259 commit 2892d65

File tree

6 files changed

+99
-14
lines changed

6 files changed

+99
-14
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ Just go to the prebuilt branch and use the download ZIP feature of Github, extra
1212

1313
If you want to take a look at a commit that's more recent, then you can download the addon as a CI build artifact from the Github workflow action.
1414

15-
Unfortunately there are no MacOS, Android, iOS, or any 32-bit binaries currently prebuilt. If you need any of those you will have to build them yourself (and in the case of mobile platforms, add them to the .gdextension file)
15+
Unfortunately there are no MacOS, Android, iOS, or any 32-bit binaries currently prebuilt. If you need any of those you will have to build them yourself and add them to the .gdextension file.
1616

1717
## Documentation
1818

addons/godot-openmpt/mpt_importer.gd

+12
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,16 @@ func _get_import_options(path, preset_index) -> Array[Dictionary]:
3434
"property_hint": PROPERTY_HINT_ENUM,
3535
"hint_string": "Disabled,Enabled",
3636
"default_value": 0
37+
},
38+
{
39+
"name": "load/skip_plugins",
40+
"type": TYPE_BOOL,
41+
"default_value": false
42+
},
43+
{
44+
"name": "load/skip_subsongs_init",
45+
"type": TYPE_BOOL,
46+
"default_value": false
3747
}]
3848

3949
func _get_option_visibility(path, option_name, options) -> bool:
@@ -57,6 +67,8 @@ func _import(source_file, save_path, options, r_platform_variants, r_gen_files)
5767
return ERR_PARSE_ERROR
5868

5969
var stream = AudioStreamMPT.new()
70+
stream.skip_plugins = options["load/skip_plugins"]
71+
stream.skip_subsongs_init = options["load/skip_subsongs_init"]
6072
stream.data = file_data
6173
if stream.data.is_empty():
6274
return stream.get_module_error()

addons/godot-openmpt/openmpt.gdextension

-4
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,7 @@ compatibility_minimum = "4.2"
77

88
macos.debug = "bin/libgdmpt-macos.debug.64.framework"
99
macos.release = "bin/libgdmpt-macos.release.64.framework"
10-
windows.debug.x86_32 = "bin/libgdmpt-windows.debug.32.dll"
11-
windows.release.x86_32 = "bin/libgdmpt-windows.release.32.dll"
1210
windows.debug.x86_64 = "bin/libgdmpt-windows.debug.64.dll"
1311
windows.release.x86_64 = "bin/libgdmpt-windows.release.64.dll"
14-
linux.debug.x86_32 = "bin/libgdmpt-linux.debug.32.so"
15-
linux.release.x86_32 = "bin/libgdmpt-linux.release.32.so"
1612
linux.debug.x86_64 = "bin/libgdmpt-linux.debug.64.so"
1713
linux.release.x86_64 = "bin/libgdmpt-linux.release.64.so"

addons/godot-openmpt/plugin.cfg

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@
33
name="Godot OpenMPT"
44
description="Integrates OpenMPT as a playable AudioStream"
55
author="Dudejoe870"
6-
version="1.0.0"
6+
version="1.3"
77
script="mpt_import.gd"

src/audio_stream_mpt.cpp

+65-8
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,13 @@ using namespace godot;
1919
#define CHECK_MOD_LOADED_RETV() if (!this->mpt_module) { WARN_PRINT_ED(MOD_NOT_LOADED_MSG); return; }
2020

2121
#define CHECK_INT_LOADED_RET(retval) CHECK_MOD_LOADED_RET(retval); if (!this->mpt_interactive) { WARN_PRINT_ED(INT_NOT_LOADED_MSG); return retval; }
22-
#define CHECK_INT_LOADED_RETV() CHECK_MOD_LOADED_RETV(); if (!this->mpt_module) { WARN_PRINT_ED(INT_NOT_LOADED_MSG); return; }
22+
#define CHECK_INT_LOADED_RETV() CHECK_MOD_LOADED_RETV(); if (!this->mpt_interactive) { WARN_PRINT_ED(INT_NOT_LOADED_MSG); return; }
2323

24-
#define CHECK_INT2_LOADED_RET(retval) CHECK_MOD_LOADED_RET(retval); if (!this->mpt_interactive) { WARN_PRINT_ED(INT2_NOT_LOADED_MSG); return retval; }
25-
#define CHECK_INT2_LOADED_RETV() CHECK_MOD_LOADED_RETV(); if (!this->mpt_module) { WARN_PRINT_ED(INT2_NOT_LOADED_MSG); return; }
24+
#define CHECK_INT2_LOADED_RET(retval) CHECK_MOD_LOADED_RET(retval); if (!this->mpt_interactive2) { WARN_PRINT_ED(INT2_NOT_LOADED_MSG); return retval; }
25+
#define CHECK_INT2_LOADED_RETV() CHECK_MOD_LOADED_RETV(); if (!this->mpt_interactive2) { WARN_PRINT_ED(INT2_NOT_LOADED_MSG); return; }
2626

27-
#define CHECK_INT3_LOADED_RET(retval) CHECK_MOD_LOADED_RET(retval); if (!this->mpt_interactive) { WARN_PRINT_ED(INT3_NOT_LOADED_MSG); return retval; }
28-
#define CHECK_INT3_LOADED_RETV() CHECK_MOD_LOADED_RETV(); if (!this->mpt_module) { WARN_PRINT_ED(INT3_NOT_LOADED_MSG); return; }
27+
#define CHECK_INT3_LOADED_RET(retval) CHECK_MOD_LOADED_RET(retval); if (!this->mpt_interactive3) { WARN_PRINT_ED(INT3_NOT_LOADED_MSG); return retval; }
28+
#define CHECK_INT3_LOADED_RETV() CHECK_MOD_LOADED_RETV(); if (!this->mpt_interactive3) { WARN_PRINT_ED(INT3_NOT_LOADED_MSG); return; }
2929

3030
void AudioStreamPlaybackMPT::_start(double p_from_pos) {
3131
_seek(p_from_pos);
@@ -285,6 +285,16 @@ double AudioStreamPlaybackMPT::get_note_finetune(int32_t channel) const {
285285
return this->mpt_interactive2->get_note_finetune(channel);
286286
}
287287

288+
void AudioStreamPlaybackMPT::set_sync_samples(bool p_enable) {
289+
CHECK_MOD_LOADED_RETV();
290+
this->mpt_module->ctl_set_boolean("seek.sync_samples", p_enable);
291+
}
292+
293+
bool AudioStreamPlaybackMPT::get_sync_samples() const {
294+
CHECK_MOD_LOADED_RET(true);
295+
return this->mpt_module->ctl_get_boolean("seek.sync_samples");
296+
}
297+
288298
int32_t AudioStreamPlaybackMPT::_mix(AudioFrame *p_buffer, double p_rate_scale, int32_t p_frames) {
289299
if (!this->mpt_module) {
290300
active = false;
@@ -382,6 +392,9 @@ void AudioStreamPlaybackMPT::_bind_methods() {
382392

383393
ClassDB::bind_method(D_METHOD("set_note_finetune", "channel", "finetune"), &AudioStreamPlaybackMPT::set_note_finetune);
384394
ClassDB::bind_method(D_METHOD("get_note_finetune", "channel"), &AudioStreamPlaybackMPT::get_note_finetune);
395+
396+
ClassDB::bind_method(D_METHOD("set_sync_samples", "sync_samples"), &AudioStreamPlaybackMPT::set_sync_samples);
397+
ClassDB::bind_method(D_METHOD("get_sync_samples"), &AudioStreamPlaybackMPT::get_sync_samples);
385398
}
386399

387400
AudioStreamPlaybackMPT::AudioStreamPlaybackMPT() {}
@@ -423,6 +436,38 @@ bool AudioStreamMPT::_is_monophonic() const {
423436
return false;
424437
}
425438

439+
void AudioStreamMPT::set_skip_plugins(bool p_enable) {
440+
this->skip_plugins = p_enable;
441+
}
442+
443+
bool AudioStreamMPT::get_skip_plugins() const {
444+
return this->skip_plugins;
445+
}
446+
447+
void AudioStreamMPT::set_skip_subsongs_init(bool p_enable) {
448+
this->skip_subsongs_init = p_enable;
449+
}
450+
451+
bool AudioStreamMPT::get_skip_subsongs_init() const {
452+
return this->skip_subsongs_init;
453+
}
454+
455+
void AudioStreamMPT::set_sync_samples(bool p_enable) {
456+
this->sync_samples = p_enable;
457+
}
458+
459+
bool AudioStreamMPT::get_sync_samples() const {
460+
return this->sync_samples;
461+
}
462+
463+
std::map<std::string, std::string> AudioStreamMPT::get_initial_ctls() const {
464+
return std::map<std::string, std::string> {
465+
{ "load.skip_plugins", this->skip_plugins ? "1" : "0" },
466+
{ "load.skip_subsongs_init", this->skip_subsongs_init ? "1" : "0" },
467+
{ "seek.sync_samples", this->sync_samples ? "1" : "0" },
468+
};
469+
}
470+
426471
void AudioStreamMPT::set_data(const PackedByteArray& p_data) {
427472
module_error = Error::OK;
428473

@@ -435,7 +480,7 @@ void AudioStreamMPT::set_data(const PackedByteArray& p_data) {
435480

436481
if (this->mpt_module) delete mpt_module;
437482
try {
438-
this->mpt_module = new openmpt::module(this->data.ptr(), this->data.size());
483+
this->mpt_module = new openmpt::module(this->data.ptr(), this->data.size(), std::clog, get_initial_ctls());
439484
} catch (openmpt::exception& e) {
440485
module_error = Error::ERR_PARSE_ERROR;
441486
goto set_empty_module;
@@ -445,7 +490,7 @@ void AudioStreamMPT::set_data(const PackedByteArray& p_data) {
445490
AudioServer::get_singleton()->lock();
446491
for (AudioStreamPlaybackMPT* playback : open_playback_objects) {
447492
if (playback->mpt_module) delete playback->mpt_module;
448-
playback->mpt_module = new openmpt::module_ext(this->data.ptr(), this->data.size());
493+
playback->mpt_module = new openmpt::module_ext(this->data.ptr(), this->data.size(), std::clog, get_initial_ctls());
449494
playback->mpt_interactive = static_cast<openmpt::ext::interactive*>(
450495
playback->mpt_module->get_interface(openmpt::ext::interactive_id));
451496
playback->mpt_interactive2 = static_cast<openmpt::ext::interactive2*>(
@@ -646,7 +691,7 @@ Ref<AudioStreamPlayback> AudioStreamMPT::_instantiate_playback() const {
646691
Ref<AudioStreamPlaybackMPT> playback;
647692
playback.instantiate();
648693
playback->base = Ref<AudioStreamMPT>(this);
649-
playback->mpt_module = !data.is_empty() ? new openmpt::module_ext(this->data.ptr(), this->data.size()) : nullptr;
694+
playback->mpt_module = !data.is_empty() ? new openmpt::module_ext(this->data.ptr(), this->data.size(), std::clog, get_initial_ctls()) : nullptr;
650695
if (playback->mpt_module)
651696
{
652697
playback->mpt_interactive = static_cast<openmpt::ext::interactive*>(
@@ -671,6 +716,14 @@ void AudioStreamMPT::_bind_methods() {
671716
ClassDB::bind_method(D_METHOD("set_stereo", "stereo"), &AudioStreamMPT::set_stereo);
672717
ClassDB::bind_method(D_METHOD("is_stereo"), &AudioStreamMPT::is_stereo);
673718

719+
ClassDB::bind_method(D_METHOD("set_skip_plugins", "skip_plugins"), &AudioStreamMPT::set_skip_plugins);
720+
ClassDB::bind_method(D_METHOD("get_skip_plugins"), &AudioStreamMPT::get_skip_plugins);
721+
ClassDB::bind_method(D_METHOD("set_skip_subsongs_init", "skip_subsongs_init"), &AudioStreamMPT::set_skip_subsongs_init);
722+
ClassDB::bind_method(D_METHOD("get_skip_subsongs_init"), &AudioStreamMPT::get_skip_subsongs_init);
723+
724+
ClassDB::bind_method(D_METHOD("set_sync_samples", "sync_samples"), &AudioStreamMPT::set_sync_samples);
725+
ClassDB::bind_method(D_METHOD("get_sync_samples"), &AudioStreamMPT::get_sync_samples);
726+
674727
ClassDB::bind_method(D_METHOD("set_data", "data"), &AudioStreamMPT::set_data);
675728
ClassDB::bind_method(D_METHOD("get_data"), &AudioStreamMPT::get_data);
676729

@@ -716,6 +769,10 @@ void AudioStreamMPT::_bind_methods() {
716769
ADD_PROPERTY(PropertyInfo(Variant::INT, "loop_mode", PROPERTY_HINT_ENUM, "Disabled,Enabled"), "set_loop_mode", "get_loop_mode");
717770
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "stereo"), "set_stereo", "is_stereo");
718771

772+
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "skip_plugins"), "set_skip_plugins", "get_skip_plugins");
773+
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "skip_subsongs_init"), "set_skip_subsongs_init", "get_skip_subsongs_init");
774+
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sync_samples"), "set_sync_samples", "get_sync_samples");
775+
719776
BIND_ENUM_CONSTANT(LOOP_DISABLED);
720777
BIND_ENUM_CONSTANT(LOOP_ENABLED);
721778

src/audio_stream_mpt.h

+20
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,9 @@ class AudioStreamPlaybackMPT : public AudioStreamPlayback {
9999
void set_note_finetune(int32_t channel, double finetune);
100100
double get_note_finetune(int32_t channel) const;
101101

102+
void set_sync_samples(bool p_enable);
103+
bool get_sync_samples() const;
104+
102105
virtual int32_t _mix(AudioFrame *p_buffer, double p_rate_scale, int32_t p_frames) override;
103106

104107
AudioStreamPlaybackMPT();
@@ -124,6 +127,9 @@ class AudioStreamMPT : public AudioStream {
124127
private:
125128
LoopMode loop_mode = LoopMode::LOOP_DISABLED;
126129
bool stereo = true;
130+
bool skip_plugins = false;
131+
bool skip_subsongs_init = false;
132+
bool sync_samples = true;
127133
PackedByteArray data;
128134

129135
// We need to create a module to parse any information about the file,
@@ -134,6 +140,8 @@ class AudioStreamMPT : public AudioStream {
134140

135141
Error module_error = Error::OK;
136142

143+
std::map<std::string, std::string> get_initial_ctls() const;
144+
137145
friend class AudioStreamPlaybackMPT;
138146
protected:
139147
static void _bind_methods();
@@ -147,6 +155,18 @@ class AudioStreamMPT : public AudioStream {
147155
virtual double _get_length() const override;
148156
virtual bool _is_monophonic() const override;
149157

158+
// Load CTLs
159+
// These only apply on the next module load.
160+
// Whether that means loading new data into this stream, or instantiating a new playback.
161+
void set_skip_plugins(bool p_enable);
162+
bool get_skip_plugins() const;
163+
void set_skip_subsongs_init(bool p_enable);
164+
bool get_skip_subsongs_init() const;
165+
166+
// Seek CTLs
167+
void set_sync_samples(bool p_enable);
168+
bool get_sync_samples() const;
169+
150170
void set_data(const PackedByteArray& p_data);
151171
const PackedByteArray& get_data() const;
152172

0 commit comments

Comments
 (0)