diff options
Diffstat (limited to 'modules/chibi/event_stream_chibi.cpp')
-rw-r--r-- | modules/chibi/event_stream_chibi.cpp | 872 |
1 files changed, 872 insertions, 0 deletions
diff --git a/modules/chibi/event_stream_chibi.cpp b/modules/chibi/event_stream_chibi.cpp new file mode 100644 index 0000000000..b88f4ee70e --- /dev/null +++ b/modules/chibi/event_stream_chibi.cpp @@ -0,0 +1,872 @@ +/*************************************************************************/ +/* event_stream_chibi.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ +#include "event_stream_chibi.h" +#include "cp_loader_it.h" +#include "cp_loader_xm.h" +#include "cp_loader_s3m.h" +#include "cp_loader_mod.h" + +static CPSampleManagerImpl *sample_manager; +static ResourceFormatLoaderChibi *resource_loader; + +CPSample_ID CPSampleManagerImpl::create(bool p_16bits,bool p_stereo,int32_t p_len) { + + AudioServer::SampleFormat sf=p_16bits?AudioServer::SAMPLE_FORMAT_PCM16:AudioServer::SAMPLE_FORMAT_PCM8; + + SampleData *sd = memnew( SampleData ); + sd->rid = AudioServer::get_singleton()->sample_create(sf,p_stereo,p_len); + sd->stereo=p_stereo; + sd->len=p_len; + sd->is16=p_16bits; + sd->mixfreq=44100; + sd->loop_begin=0; + sd->loop_end=0; + sd->loop_type=CP_LOOP_NONE; + sd->locks=0; +#ifdef DEBUG_ENABLED + valid.insert(sd); +#endif + CPSample_ID sid; + sid._private=sd; + return sid; +} + +void CPSampleManagerImpl::recreate(CPSample_ID p_id,bool p_16bits,bool p_stereo,int32_t p_len){ + + AudioServer::SampleFormat sf=p_16bits?AudioServer::SAMPLE_FORMAT_PCM16:AudioServer::SAMPLE_FORMAT_PCM8; + SampleData *sd=_getsd(p_id); +#ifdef DEBUG_ENABLED + ERR_FAIL_COND(!valid.has(sd)); +#endif + AudioServer::get_singleton()->free(sd->rid); + sd->rid = AudioServer::get_singleton()->sample_create(sf,p_stereo,p_len); + sd->stereo=p_stereo; + sd->len=p_len; + sd->is16=p_16bits; + sd->mixfreq=44100; + sd->loop_begin=0; + sd->loop_end=0; + sd->loop_type=CP_LOOP_NONE; +} +void CPSampleManagerImpl::destroy(CPSample_ID p_id){ + + SampleData *sd=_getsd(p_id); +#ifdef DEBUG_ENABLED + ERR_FAIL_COND(!valid.has(sd)); + valid.erase(sd); +#endif + AudioServer::get_singleton()->free(sd->rid); + + memdelete(sd); +} +bool CPSampleManagerImpl::check(CPSample_ID p_id){ + + SampleData *sd=_getsd(p_id); +#ifdef DEBUG_ENABLED + return valid.has(sd); +#else + return _getsd(p_id)!=NULL; +#endif +} + +void CPSampleManagerImpl::set_c5_freq(CPSample_ID p_id,int32_t p_freq){ + + SampleData *sd=_getsd(p_id); +#ifdef DEBUG_ENABLED + ERR_FAIL_COND(!valid.has(sd)); +#endif + sd->mixfreq=p_freq; + AudioServer::get_singleton()->sample_set_mix_rate(sd->rid,p_freq); + +} +void CPSampleManagerImpl::set_loop_begin(CPSample_ID p_id,int32_t p_begin){ + + SampleData *sd=_getsd(p_id); +#ifdef DEBUG_ENABLED + ERR_FAIL_COND(!valid.has(sd)); +#endif + sd->loop_begin=p_begin; + AudioServer::get_singleton()->sample_set_loop_begin(sd->rid,p_begin); + +} +void CPSampleManagerImpl::set_loop_end(CPSample_ID p_id,int32_t p_end){ + + SampleData *sd=_getsd(p_id); +#ifdef DEBUG_ENABLED + ERR_FAIL_COND(!valid.has(sd)); +#endif + sd->loop_end=p_end; + AudioServer::get_singleton()->sample_set_loop_end(sd->rid,p_end); + +} +void CPSampleManagerImpl::set_loop_type(CPSample_ID p_id,CPSample_Loop_Type p_type){ + + SampleData *sd=_getsd(p_id); +#ifdef DEBUG_ENABLED + ERR_FAIL_COND(!valid.has(sd)); +#endif + + sd->loop_type=p_type; + AudioServer::get_singleton()->sample_set_loop_format(sd->rid,AudioServer::SampleLoopFormat(p_type)); + + +} +void CPSampleManagerImpl::set_chunk(CPSample_ID p_id,int32_t p_index,void *p_data,int p_data_len){ + + SampleData *sd=_getsd(p_id); +#ifdef DEBUG_ENABLED + ERR_FAIL_COND(!valid.has(sd)); +#endif + + ERR_FAIL(); +} + + +int32_t CPSampleManagerImpl::get_loop_begin(CPSample_ID p_id){ + + SampleData *sd=_getsd(p_id); +#ifdef DEBUG_ENABLED + ERR_FAIL_COND_V(!valid.has(sd),0); +#endif + + return sd->loop_begin; + +} +int32_t CPSampleManagerImpl::get_loop_end(CPSample_ID p_id){ + + SampleData *sd=_getsd(p_id); +#ifdef DEBUG_ENABLED + ERR_FAIL_COND_V(!valid.has(sd),0); +#endif + + return sd->loop_end; +} +CPSample_Loop_Type CPSampleManagerImpl::get_loop_type(CPSample_ID p_id){ + + SampleData *sd=_getsd(p_id); +#ifdef DEBUG_ENABLED + ERR_FAIL_COND_V(!valid.has(sd),CP_LOOP_NONE); +#endif + + return sd->loop_type; +} +int32_t CPSampleManagerImpl::get_c5_freq(CPSample_ID p_id){ + + SampleData *sd=_getsd(p_id); +#ifdef DEBUG_ENABLED + ERR_FAIL_COND_V(!valid.has(sd),0); +#endif + + return sd->mixfreq; +} +int32_t CPSampleManagerImpl::get_size(CPSample_ID p_id){ + + SampleData *sd=_getsd(p_id); +#ifdef DEBUG_ENABLED + ERR_FAIL_COND_V(!valid.has(sd),0); +#endif + + return sd->len; + +} +bool CPSampleManagerImpl::is_16bits(CPSample_ID p_id){ + + SampleData *sd=_getsd(p_id); +#ifdef DEBUG_ENABLED + ERR_FAIL_COND_V(!valid.has(sd),false); +#endif + + return sd->is16; + +} +bool CPSampleManagerImpl::is_stereo(CPSample_ID p_id){ + + SampleData *sd=_getsd(p_id); +#ifdef DEBUG_ENABLED + ERR_FAIL_COND_V(!valid.has(sd),false); +#endif + return sd->stereo; + + +} +bool CPSampleManagerImpl::lock_data(CPSample_ID p_id){ + + SampleData *sd=_getsd(p_id); +#ifdef DEBUG_ENABLED + ERR_FAIL_COND_V(!valid.has(sd),0); +#endif + + sd->locks++; + if (sd->locks==1) { + sd->lock=AudioServer::get_singleton()->sample_get_data(sd->rid); + sd->w=sd->lock.write(); + } + + return true; +} +void *CPSampleManagerImpl::get_data(CPSample_ID p_id){ + + SampleData *sd=_getsd(p_id); +#ifdef DEBUG_ENABLED + ERR_FAIL_COND_V(!valid.has(sd),0); +#endif + + ERR_FAIL_COND_V(sd->locks==0,0); + return sd->w.ptr(); +} + +int16_t CPSampleManagerImpl::get_data(CPSample_ID p_id, int p_sample, int p_channel){ + + SampleData *sd=_getsd(p_id); +#ifdef DEBUG_ENABLED + ERR_FAIL_COND_V(!valid.has(sd),0); +#endif + + ERR_FAIL_V(0); + lock_data(p_id); + + int sofs = sd->stereo ? 2:1; + uint16_t v=0; + if (sd->is16) { + int16_t *p=(int16_t*)sd->w.ptr(); + v=p[p_sample*sofs+p_channel]; + } else { + int8_t *p=(int8_t*)sd->w.ptr(); + v=p[p_sample*sofs+p_channel]; + } + + unlock_data(p_id); + + return v; +} +void CPSampleManagerImpl::set_data(CPSample_ID p_id, int p_sample, int16_t p_data,int p_channel){ + + SampleData *sd=_getsd(p_id); +#ifdef DEBUG_ENABLED + ERR_FAIL_COND(!valid.has(sd)); +#endif + + ERR_FAIL(); + lock_data(p_id); + + int sofs = sd->stereo ? 2:1; + if (sd->is16) { + int16_t *p=(int16_t*)sd->w.ptr(); + p[p_sample*sofs+p_channel]=p_data; + } else { + int8_t *p=(int8_t*)sd->w.ptr(); + p[p_sample*sofs+p_channel]=p_data; + } + + unlock_data(p_id); + +} +void CPSampleManagerImpl::unlock_data(CPSample_ID p_id){ + + SampleData *sd=_getsd(p_id); +#ifdef DEBUG_ENABLED + ERR_FAIL_COND(!valid.has(sd)); +#endif + + ERR_FAIL_COND(sd->locks==0); + + sd->locks--; + if (sd->locks==0) { + sd->w=DVector<uint8_t>::Write(); + AudioServer::get_singleton()->sample_set_data(sd->rid,sd->lock); + sd->lock=DVector<uint8_t>(); + } +} + +void CPSampleManagerImpl::get_chunk(CPSample_ID p_id,int32_t p_index,void *p_data,int p_data_len) { + + SampleData *sd=_getsd(p_id); +#ifdef DEBUG_ENABLED + ERR_FAIL_COND(!valid.has(sd)); +#endif + + ERR_FAIL(); +} + + +/** MIXER **/ + +void CPMixerImpl::set_callback_interval(int p_interval_us) { + + callback_interval=p_interval_us; +} + +void CPMixerImpl::set_callback(void (*p_callback)(void*),void *p_userdata) { + + callback=p_callback; + userdata=p_userdata; +} + +void CPMixerImpl::setup_voice(int p_voice_index,CPSample_ID p_sample_id,int32_t p_start_index) { + + Voice &v=voices[p_voice_index]; + if (v.channel!=AudioMixer::INVALID_CHANNEL) { + mixer->channel_free(v.channel); + } + v.channel=mixer->channel_alloc(sample_manager->get_rid(p_sample_id)); + v.freq_mult = sample_manager->get_c5_freq(p_sample_id)/261.6255653006; + v.sample = p_sample_id; +} + +void CPMixerImpl::stop_voice(int p_voice_index) { + + Voice &v=voices[p_voice_index]; + if (v.channel==AudioMixer::INVALID_CHANNEL) + return; + + mixer->channel_free(v.channel); + v.channel=AudioMixer::INVALID_CHANNEL; + +} + +void CPMixerImpl::set_voice_frequency(int p_voice_index,int32_t p_freq) { + + Voice &v=voices[p_voice_index]; + ERR_FAIL_COND(v.channel==AudioMixer::INVALID_CHANNEL); + float f = p_freq / 256.0; + f*=pitch_scale; + mixer->channel_set_mix_rate(v.channel,f * v.freq_mult ); +} + +void CPMixerImpl::set_voice_panning(int p_voice_index,int p_pan) { + + Voice &v=voices[p_voice_index]; + ERR_FAIL_COND(v.channel==AudioMixer::INVALID_CHANNEL); + if (p_pan==CP_PAN_SURROUND) + p_pan=CP_PAN_CENTER; + float p = p_pan / 256.0; + mixer->channel_set_pan(v.channel,p); + +} + +void CPMixerImpl::set_voice_volume(int p_voice_index,int p_vol) { + + + Voice &v=voices[p_voice_index]; + ERR_FAIL_COND(v.channel==AudioMixer::INVALID_CHANNEL); + float vol = p_vol/512.0; + vol*=voice_scale; + mixer->channel_set_volume(v.channel,vol); + mixer->channel_set_reverb(v.channel,reverb_type,vol*v.reverb); +} + +void CPMixerImpl::set_voice_filter(int p_voice_index,bool p_enabled,uint8_t p_cutoff, uint8_t p_resonance ){ + + Voice &v=voices[p_voice_index]; + ERR_FAIL_COND(v.channel==AudioMixer::INVALID_CHANNEL); + +} + +void CPMixerImpl::set_voice_reverb_send(int p_voice_index,int p_reverb){ + + Voice &v=voices[p_voice_index]; + ERR_FAIL_COND(v.channel==AudioMixer::INVALID_CHANNEL); + v.reverb=p_reverb/255.0; + //mixer->channel_set_reverb(v.channel,reverb_type,p_reverb/255.0); + +} + +void CPMixerImpl::set_voice_chorus_send(int p_voice_index,int p_chorus){ + + Voice &v=voices[p_voice_index]; + ERR_FAIL_COND(v.channel==AudioMixer::INVALID_CHANNEL); + mixer->channel_set_chorus(v.channel,p_chorus/255.0); + +} + + +void CPMixerImpl::set_reverb_mode(ReverbMode p_mode){ + +// Voice &v=voices[p_voice_index]; +// ERR_FAIL_COND(v.channel==AudioMixer::INVALID_CHANNEL); + switch(p_mode) { + case CPMixer::REVERB_MODE_STUDIO_SMALL: reverb_type=AudioMixer::REVERB_SMALL; break; + case CPMixer::REVERB_MODE_STUDIO_MEDIUM: reverb_type=AudioMixer::REVERB_MEDIUM; break; + case CPMixer::REVERB_MODE_STUDIO_LARGE: reverb_type=AudioMixer::REVERB_LARGE; break; + case CPMixer::REVERB_MODE_HALL: reverb_type=AudioMixer::REVERB_HALL; break; + default: reverb_type=AudioMixer::REVERB_SMALL; break; + } + +} + +void CPMixerImpl::set_chorus_params(unsigned int p_delay_ms,unsigned int p_separation_ms,unsigned int p_depth_ms10,unsigned int p_speed_hz10){ + +// Voice &v=voices[p_voice_index]; +// ERR_FAIL_COND(v.channel==AudioMixer::INVALID_CHANNEL); + +} + + + +/* Info retrieving */ + +int32_t CPMixerImpl::get_voice_sample_pos_index(int p_voice_index) { + + Voice &v=voices[p_voice_index]; + ERR_FAIL_COND_V(v.channel==AudioMixer::INVALID_CHANNEL,0); + return 0; + +} + +int CPMixerImpl::get_voice_panning(int p_voice_index) { + + Voice &v=voices[p_voice_index]; + ERR_FAIL_COND_V(!is_voice_active(p_voice_index),0); + return mixer->channel_get_pan(v.channel)*CP_PAN_RIGHT; + +} + +int CPMixerImpl::get_voice_volume(int p_voice_index) { + + Voice &v=voices[p_voice_index]; + ERR_FAIL_COND_V(!is_voice_active(p_voice_index),0); + return mixer->channel_get_volume(v.channel); + + +} + +CPSample_ID CPMixerImpl::get_voice_sample_id(int p_voice_index) { + + Voice &v=voices[p_voice_index]; + ERR_FAIL_COND_V(v.channel==AudioMixer::INVALID_CHANNEL,CPSample_ID()); + return v.sample; + + +} + +bool CPMixerImpl::is_voice_active(int p_voice_index){ + + Voice &v=voices[p_voice_index]; + if (v.channel==AudioMixer::INVALID_CHANNEL) + return false; + if (!mixer->channel_is_valid(v.channel)) + v.channel=AudioMixer::INVALID_CHANNEL; + + return v.channel!=AudioMixer::INVALID_CHANNEL; +} + +void CPMixerImpl::process_usecs(int p_usec,float p_volume,float p_pitch_scale,float p_tempo_scale) { + + ERR_FAIL_COND(callback_interval==0); + //update this somewhere + pitch_scale=p_pitch_scale; + tempo_scale=p_tempo_scale; + voice_scale = AudioServer::get_singleton()->get_event_voice_global_volume_scale()*p_volume; + while(p_usec) { + + if (p_usec>=callback_timeout) { + + p_usec-=callback_timeout; + callback_timeout=0; + if (callback) { + callback(userdata); + } + callback_timeout=callback_interval*(1.0/p_tempo_scale); + + } else { + + callback_timeout-=p_usec; + p_usec=0; + } + } +} + + +CPMixerImpl::CPMixerImpl(AudioMixer *p_mixer) { + + callback_interval=1; + callback_timeout=0; + userdata=0; + callback=0; + tempo_scale=1.0; + pitch_scale=1.0; + mixer=p_mixer; + voice_scale = AudioServer::get_singleton()->get_event_voice_global_volume_scale(); + reverb_type = AudioMixer::REVERB_SMALL; + +} + +/** FILE ACCESS WRAPPER **/ + + +CPFileAccessWrapperImpl::Error CPFileAccessWrapperImpl::open(const char *p_filename, int p_mode_flags) { + + ERR_FAIL_COND_V(p_mode_flags&WRITE,ERROR_WRITING_FILE); + close(); + f = FileAccess::open(String::utf8(p_filename),p_mode_flags); + if (!f) + return ERROR_FILE_NOT_FOUND; + return OK; +} + +void CPFileAccessWrapperImpl::close(){ + + if (f) + memdelete(f); + f=NULL; + + +} + +void CPFileAccessWrapperImpl::seek(uint32_t p_position){ + + f->seek(p_position); +} +void CPFileAccessWrapperImpl::seek_end(){ + + f->seek_end(); +} +uint32_t CPFileAccessWrapperImpl::get_pos(){ + + return f->get_pos(); +} + +bool CPFileAccessWrapperImpl::eof_reached(){ + + return f->eof_reached(); +} + +uint8_t CPFileAccessWrapperImpl::get_byte(){ + + return f->get_8(); +} +void CPFileAccessWrapperImpl::get_byte_array(uint8_t *p_dest,int p_elements){ + + f->get_buffer(p_dest,p_elements); +} +void CPFileAccessWrapperImpl::get_word_array(uint16_t *p_dest,int p_elements){ + + for(int i=0;i<p_elements;i++) { + p_dest[i]=f->get_16(); + } + +} + +uint16_t CPFileAccessWrapperImpl::get_word(){ + + return f->get_16(); +} +uint32_t CPFileAccessWrapperImpl::get_dword(){ + + return f->get_32(); +} + +void CPFileAccessWrapperImpl::set_endian_conversion(bool p_swap){ + + f->set_endian_swap(p_swap); +} +bool CPFileAccessWrapperImpl::is_open(){ + + return f!=NULL; +} + +CPFileAccessWrapperImpl::Error CPFileAccessWrapperImpl::get_error(){ + + return (f->get_error()!=::OK)?ERROR_READING_FILE:OK; +} + +void CPFileAccessWrapperImpl::store_byte(uint8_t p_dest){ + +} +void CPFileAccessWrapperImpl::store_byte_array(const uint8_t *p_dest,int p_elements){ + +} + +void CPFileAccessWrapperImpl::store_word(uint16_t p_dest){ + +} +void CPFileAccessWrapperImpl::store_dword(uint32_t p_dest){ + +} + +//////////////////////////////////////////////// + + +Error EventStreamPlaybackChibi::_play() { + + last_order=0; + loops=0; + player->play_start_song(); + total_usec=0; + + return OK; +} + +bool EventStreamPlaybackChibi::_update(AudioMixer* p_mixer, uint64_t p_usec){ + + total_usec+=p_usec; + mixer.process_usecs(p_usec,volume,pitch_scale,tempo_scale); + int order=player->get_current_order(); + if (order<last_order) { + if (!loop) { + stop(); + } else { + loops++; + } + } + last_order=order; + return false; +} +void EventStreamPlaybackChibi::_stop(){ + + player->play_stop(); +} + +void EventStreamPlaybackChibi::set_paused(bool p_paused){ + +} +bool EventStreamPlaybackChibi::is_paused() const{ + + return false; +} +void EventStreamPlaybackChibi::set_loop(bool p_loop){ + + loop=p_loop; + +} +bool EventStreamPlaybackChibi::is_loop_enabled() const{ + + return loop; +} + +int EventStreamPlaybackChibi::get_loop_count() const{ + + //return player->is + return loops; +} + +float EventStreamPlaybackChibi::get_pos() const{ + + return double(total_usec)/1000000.0; +} +void EventStreamPlaybackChibi::seek_pos(float p_time){ + + WARN_PRINT("seek_pos unimplemented."); +} + +void EventStreamPlaybackChibi::set_volume(float p_volume) { + + volume=p_volume; +} + +float EventStreamPlaybackChibi::get_volume() const{ + + return volume; +} + +void EventStreamPlaybackChibi::set_pitch_scale(float p_pitch_scale) { + + pitch_scale=p_pitch_scale; +} + +float EventStreamPlaybackChibi::get_pitch_scale() const{ + + return pitch_scale; +} + +void EventStreamPlaybackChibi::set_tempo_scale(float p_tempo_scale) { + + tempo_scale=p_tempo_scale; +} + +float EventStreamPlaybackChibi::get_tempo_scale() const{ + + return tempo_scale; +} + + +void EventStreamPlaybackChibi::set_channel_volume(int p_channel,float p_volume) { + + + if (p_channel>=64) + return; + player->set_channel_global_volume(p_channel,p_volume*256); +} + + + +float EventStreamPlaybackChibi::get_channel_volume(int p_channel) const{ + + return player->get_channel_global_volume(p_channel)/256.0; + +} + +float EventStreamPlaybackChibi::get_last_note_time(int p_channel) const { + + + double v = (player->get_channel_last_note_time_usec(p_channel))/1000000.0; + if (v<0) + v=-1; + return v; +} + +EventStreamPlaybackChibi::EventStreamPlaybackChibi(Ref<EventStreamChibi> p_stream) : mixer(_get_mixer()) { + + stream=p_stream; + player = memnew( CPPlayer(&mixer,&p_stream->song) ); + loop=false; + last_order=0; + loops=0; + volume=1.0; + pitch_scale=1.0; + tempo_scale=1.0; +} +EventStreamPlaybackChibi::~EventStreamPlaybackChibi(){ + + player->play_stop(); + memdelete(player); +} + +//////////////////////////////////////////////////// + +Ref<EventStreamPlayback> EventStreamChibi::instance_playback() { + + return Ref<EventStreamPlayback>( memnew(EventStreamPlaybackChibi(Ref<EventStreamChibi>(this))) ); +} + +String EventStreamChibi::get_stream_name() const{ + + return song.get_name(); + +} + + + +float EventStreamChibi::get_length() const{ + + return 1; +} + + +EventStreamChibi::EventStreamChibi() { + + +} + + + +////////////////////////////////////////////////////////////////// + + + + +RES ResourceFormatLoaderChibi::load(const String &p_path, const String& p_original_path, Error *r_error) { + + if (r_error) + *r_error=ERR_FILE_CANT_OPEN; + String el = p_path.extension().to_lower(); + + CPFileAccessWrapperImpl f; + + if (el=="it") { + + Ref<EventStreamChibi> esc( memnew( EventStreamChibi ) ); + CPLoader_IT loader(&f); + CPLoader::Error err = loader.load_song(p_path.utf8().get_data(),&esc->song,false); + ERR_FAIL_COND_V(err!=CPLoader::FILE_OK,RES()); + if (r_error) + *r_error=OK; + + return esc; + + } else if (el=="xm") { + + Ref<EventStreamChibi> esc( memnew( EventStreamChibi ) ); + CPLoader_XM loader(&f); + CPLoader::Error err=loader.load_song(p_path.utf8().get_data(),&esc->song,false); + ERR_FAIL_COND_V(err!=CPLoader::FILE_OK,RES()); + if (r_error) + *r_error=OK; + return esc; + + } else if (el=="s3m") { + + Ref<EventStreamChibi> esc( memnew( EventStreamChibi ) ); + CPLoader_S3M loader(&f); + CPLoader::Error err=loader.load_song(p_path.utf8().get_data(),&esc->song,false); + ERR_FAIL_COND_V(err!=CPLoader::FILE_OK,RES()); + if (r_error) + *r_error=OK; + + return esc; + + } else if (el=="mod") { + + Ref<EventStreamChibi> esc( memnew( EventStreamChibi ) ); + CPLoader_MOD loader(&f); + CPLoader::Error err=loader.load_song(p_path.utf8().get_data(),&esc->song,false); + ERR_FAIL_COND_V(err!=CPLoader::FILE_OK,RES()); + if (r_error) + *r_error=OK; + return esc; + } + + return RES(); + +} + +void ResourceFormatLoaderChibi::get_recognized_extensions(List<String> *p_extensions) const { + + p_extensions->push_back("it"); + p_extensions->push_back("xm"); + p_extensions->push_back("s3m"); + p_extensions->push_back("mod"); +} +bool ResourceFormatLoaderChibi::handles_type(const String& p_type) const { + + return (p_type=="EventStreamChibi" || p_type=="EventStream"); +} + +String ResourceFormatLoaderChibi::get_resource_type(const String &p_path) const { + String el = p_path.extension().to_lower(); + if (el=="it" || el=="s3m" || el=="xm" || el=="mod") + return "EventStreamChibi"; + return ""; +} + +///////////////////////////////////////////////////////////////// +void initialize_chibi() { + + sample_manager = memnew( CPSampleManagerImpl ); + resource_loader = memnew( ResourceFormatLoaderChibi ); + ObjectTypeDB::register_type<EventStreamChibi>(); + ResourceLoader::add_resource_format_loader( resource_loader ); +} + +void finalize_chibi() { + + memdelete( sample_manager ); + memdelete( resource_loader ); +} + |