@@ -37,6 +37,8 @@ OTHER DEALINGS IN THE SOFTWARE.
3737#include <string.h>
3838#include "memwriter.h"
3939#include <time.h>
40+ #include <unistd.h>
41+ #include "wavewriter.h"
4042
4143extern Mused mused ;
4244extern GfxDomain * domain ;
@@ -111,6 +113,18 @@ static void write_wavetable_entry(SDL_RWops *f, const CydWavetableEntry *write_w
111113 }
112114}
113115
116+
117+ /* Write max 255 character string
118+ */
119+
120+ static void write_string8 (SDL_RWops * f , const char * string )
121+ {
122+ Uint8 len = strlen (string );
123+ SDL_RWwrite (f , & len , sizeof (len ), 1 );
124+ if (len )
125+ SDL_RWwrite (f , string , sizeof (string [0 ]), len );
126+ }
127+
114128
115129static void save_instrument_inner (SDL_RWops * f , MusInstrument * inst , const CydWavetableEntry * write_wave , const CydWavetableEntry * write_wave_fm )
116130{
@@ -146,10 +160,9 @@ static void save_instrument_inner(SDL_RWops *f, MusInstrument *inst, const CydWa
146160 SDL_RWwrite (f , & inst -> slide_speed , sizeof (inst -> slide_speed ), 1 );
147161 SDL_RWwrite (f , & inst -> base_note , sizeof (inst -> base_note ), 1 );
148162 SDL_RWwrite (f , & inst -> finetune , sizeof (inst -> finetune ), 1 );
149- Uint8 len = strlen (inst -> name );
150- SDL_RWwrite (f , & len , sizeof (len ), 1 );
151- if (len )
152- SDL_RWwrite (f , & inst -> name , sizeof (inst -> name [0 ]), len );
163+
164+ write_string8 (f , inst -> name );
165+
153166 temp16 = inst -> cutoff ;
154167 FIX_ENDIAN (temp16 );
155168 SDL_RWwrite (f , & temp16 , sizeof (temp16 ), 1 );
@@ -205,6 +218,41 @@ static void save_instrument_inner(SDL_RWops *f, MusInstrument *inst, const CydWa
205218}
206219
207220
221+ static void save_fx_inner (SDL_RWops * f , CydFxSerialized * fx )
222+ {
223+ CydFxSerialized temp ;
224+ memcpy (& temp , fx , sizeof (temp ));
225+
226+ FIX_ENDIAN (temp .flags );
227+ for (int i = 0 ; i < CYDRVB_TAPS ; ++ i )
228+ {
229+ FIX_ENDIAN (temp .rvb .tap [i ].gain );
230+ FIX_ENDIAN (temp .rvb .tap [i ].delay );
231+ }
232+
233+ write_string8 (f , temp .name );
234+
235+ SDL_RWwrite (f , & temp .flags , sizeof (temp .flags ), 1 );
236+ SDL_RWwrite (f , & temp .crush .bit_drop , sizeof (temp .crush .bit_drop ), 1 );
237+ SDL_RWwrite (f , & temp .chr .rate , sizeof (temp .chr .rate ), 1 );
238+ SDL_RWwrite (f , & temp .chr .min_delay , sizeof (temp .chr .min_delay ), 1 );
239+ SDL_RWwrite (f , & temp .chr .max_delay , sizeof (temp .chr .max_delay ), 1 );
240+ SDL_RWwrite (f , & temp .chr .sep , sizeof (temp .chr .sep ), 1 );
241+
242+ for (int i = 0 ; i < CYDRVB_TAPS ; ++ i )
243+ {
244+ SDL_RWwrite (f , & temp .rvb .tap [i ].delay , sizeof (temp .rvb .tap [i ].delay ), 1 );
245+ SDL_RWwrite (f , & temp .rvb .tap [i ].gain , sizeof (temp .rvb .tap [i ].gain ), 1 );
246+ SDL_RWwrite (f , & temp .rvb .tap [i ].panning , sizeof (temp .rvb .tap [i ].panning ), 1 );
247+ SDL_RWwrite (f , & temp .rvb .tap [i ].flags , sizeof (temp .rvb .tap [i ].flags ), 1 );
248+ }
249+
250+ SDL_RWwrite (f , & temp .crushex .downsample , sizeof (temp .crushex .downsample ), 1 );
251+ SDL_RWwrite (f , & temp .crushex .gain , sizeof (temp .crushex .gain ), 1 );
252+ }
253+
254+
255+
208256static void write_packed_pattern (SDL_RWops * f , const MusPattern * pattern , bool skip )
209257{
210258 /*
@@ -327,6 +375,14 @@ int open_song(FILE *f)
327375 for (int i = 0 ; i < mused .song .num_patterns ; ++ i )
328376 if (mused .song .pattern [i ].num_steps == 0 )
329377 resize_pattern (& mused .song .pattern [i ], mused .default_pattern_length );
378+
379+ mused .song .wavetable_names = realloc (mused .song .wavetable_names , sizeof (mused .song .wavetable_names [0 ]) * CYD_WAVE_MAX_ENTRIES );
380+
381+ for (int i = mused .song .num_wavetables ; i < CYD_WAVE_MAX_ENTRIES ; ++ i )
382+ {
383+ mused .song .wavetable_names [i ] = malloc (MUS_WAVETABLE_NAME_LEN + 1 );
384+ memset (mused .song .wavetable_names [i ], 0 , MUS_WAVETABLE_NAME_LEN + 1 );
385+ }
330386
331387 set_channels (mused .song .num_channels );
332388
@@ -348,6 +404,20 @@ int save_instrument(SDL_RWops *f)
348404}
349405
350406
407+ int save_fx (SDL_RWops * f )
408+ {
409+ const Uint8 version = MUS_VERSION ;
410+
411+ SDL_RWwrite (f , MUS_FX_SIG , strlen (MUS_FX_SIG ), sizeof (MUS_FX_SIG [0 ]));
412+
413+ SDL_RWwrite (f , & version , 1 , sizeof (version ));
414+
415+ save_fx_inner (f , & mused .song .fx [mused .fx_bus ]);
416+
417+ return 1 ;
418+ }
419+
420+
351421int save_song_inner (SDL_RWops * f , SongStats * stats )
352422{
353423 bool kill_unused_things = false;
@@ -417,10 +487,7 @@ int save_song_inner(SDL_RWops *f, SongStats *stats)
417487 SDL_RWwrite (f , & mused .song .multiplex_period , 1 , sizeof (mused .song .multiplex_period ));
418488 SDL_RWwrite (f , & mused .song .pitch_inaccuracy , 1 , sizeof (mused .song .pitch_inaccuracy ));
419489
420- Uint8 len = strlen (mused .song .title );
421- SDL_RWwrite (f , & len , 1 , 1 );
422- if (len )
423- SDL_RWwrite (f , mused .song .title , 1 , len );
490+ write_string8 (f , mused .song .title );
424491
425492 if (stats )
426493 stats -> size [STATS_HEADER ] = SDL_RWtell (f );
@@ -441,38 +508,7 @@ int save_song_inner(SDL_RWops *f, SongStats *stats)
441508 debug ("Saving %d fx" , n_fx );
442509 for (int fx = 0 ; fx < n_fx ; ++ fx )
443510 {
444- CydFxSerialized temp ;
445- memcpy (& temp , & mused .song .fx [fx ], sizeof (temp ));
446-
447- FIX_ENDIAN (temp .flags );
448- for (int i = 0 ; i < CYDRVB_TAPS ; ++ i )
449- {
450- FIX_ENDIAN (temp .rvb .tap [i ].gain );
451- FIX_ENDIAN (temp .rvb .tap [i ].delay );
452- }
453-
454- Uint8 len = strlen (temp .name );
455- SDL_RWwrite (f , & len , sizeof (len ), 1 );
456- if (len )
457- SDL_RWwrite (f , temp .name , sizeof (temp .name [0 ]), len );
458-
459- SDL_RWwrite (f , & temp .flags , sizeof (temp .flags ), 1 );
460- SDL_RWwrite (f , & temp .crush .bit_drop , sizeof (temp .crush .bit_drop ), 1 );
461- SDL_RWwrite (f , & temp .chr .rate , sizeof (temp .chr .rate ), 1 );
462- SDL_RWwrite (f , & temp .chr .min_delay , sizeof (temp .chr .min_delay ), 1 );
463- SDL_RWwrite (f , & temp .chr .max_delay , sizeof (temp .chr .max_delay ), 1 );
464- SDL_RWwrite (f , & temp .chr .sep , sizeof (temp .chr .sep ), 1 );
465-
466- SDL_RWwrite (f , & temp .rvb .spread , sizeof (temp .rvb .spread ), 1 );
467-
468- for (int i = 0 ; i < CYDRVB_TAPS ; ++ i )
469- {
470- SDL_RWwrite (f , & temp .rvb .tap [i ].delay , sizeof (temp .rvb .tap [i ].delay ), 1 );
471- SDL_RWwrite (f , & temp .rvb .tap [i ].gain , sizeof (temp .rvb .tap [i ].gain ), 1 );
472- }
473-
474- SDL_RWwrite (f , & temp .crushex .downsample , sizeof (temp .crushex .downsample ), 1 );
475- SDL_RWwrite (f , & temp .crushex .gain , sizeof (temp .crushex .gain ), 1 );
511+ save_fx_inner (f , & mused .song .fx [fx ]);
476512 }
477513
478514 if (stats )
@@ -547,6 +583,14 @@ int save_song_inner(SDL_RWops *f, SongStats *stats)
547583 if (stats )
548584 stats -> size [STATS_WAVETABLE ] = SDL_RWtell (f );
549585
586+ for (int i = 0 ; i < max_wt ; ++ i )
587+ {
588+ write_string8 (f , mused .song .wavetable_names [i ]);
589+ }
590+
591+ if (stats )
592+ stats -> size [STATS_WAVETABLE_NAMES ] = SDL_RWtell (f );
593+
550594 mused .song .num_patterns = NUM_PATTERNS ;
551595 mused .song .num_instruments = NUM_INSTRUMENTS ;
552596
@@ -649,6 +693,18 @@ int open_instrument(FILE *f)
649693}
650694
651695
696+ int open_fx (FILE * f )
697+ {
698+ if (!mus_load_fx_file (f , & mused .song .fx [mused .fx_bus ])) return 0 ;
699+
700+ mused .modified = true;
701+
702+ mus_set_fx (& mused .mus , & mused .song );
703+
704+ return 1 ;
705+ }
706+
707+
652708int save_song (SDL_RWops * ops )
653709{
654710 int r = save_song_inner (ops , NULL );
@@ -659,6 +715,17 @@ int save_song(SDL_RWops *ops)
659715}
660716
661717
718+ int save_wavetable (FILE * ops )
719+ {
720+ WaveWriter * ww = ww_create (ops , mused .mus .cyd -> wavetable_entries [mused .selected_wavetable ].sample_rate , 1 );
721+
722+ ww_write (ww , mused .mus .cyd -> wavetable_entries [mused .selected_wavetable ].data , mused .mus .cyd -> wavetable_entries [mused .selected_wavetable ].samples );
723+
724+ ww_finish (ww );
725+ return 1 ;
726+ }
727+
728+
662729void open_data (void * type , void * action , void * _ret )
663730{
664731 int t = CASTPTR (int , type );
@@ -699,7 +766,8 @@ void open_data(void *type, void *action, void *_ret)
699766 { "instrument" , "ki" , open_instrument , save_instrument },
700767 { "wave" , "wav" , open_wavetable , NULL },
701768 { "raw signed" , "" , open_wavetable_raw , NULL },
702- { "raw unsigned" , "" , open_wavetable_raw_u , NULL }
769+ { "raw unsigned" , "" , open_wavetable_raw_u , NULL },
770+ { "FX bus" , "kx" , open_fx , save_fx }
703771 };
704772
705773 const char * mode [] = { "rb" , "wb" };
@@ -722,6 +790,12 @@ void open_data(void *type, void *action, void *_ret)
722790 }
723791 break ;
724792
793+ case OD_T_FX :
794+ {
795+ snprintf (_def , sizeof (_def ), "%s.kx" , mused .song .fx [mused .fx_bus ].name );
796+ }
797+ break ;
798+
725799 case OD_T_SONG :
726800 {
727801 if (strlen (mused .previous_song_filename ) == 0 )
@@ -743,8 +817,13 @@ void open_data(void *type, void *action, void *_ret)
743817 FILE * f = NULL ;
744818 SDL_RWops * rw = NULL ;
745819
820+ if (mused .previous_filebox_path [t ][0 ])
821+ chdir (mused .previous_filebox_path [t ]);
822+
746823 if (open_dialog_fn (mode [a ], str , open_stuff [t ].ext , domain , mused .slider_bevel , & mused .largefont , & mused .smallfont , def , filename , sizeof (filename )))
747824 {
825+ getcwd (mused .previous_filebox_path [t ], sizeof (mused .previous_filebox_path [t ]));
826+
748827 if (!(mused .flags & DISABLE_BACKUPS ) && a == OD_A_SAVE && !create_backup (filename ))
749828 warning ("Could not create backup for %s" , filename );
750829
@@ -765,16 +844,23 @@ void open_data(void *type, void *action, void *_ret)
765844 else
766845 tmp = open_stuff [t ].save ;
767846
768- if (tmp )
847+ if (tmp || (( t == OD_T_WAVETABLE ) && ( a == 1 )) )
769848 {
770849 cyd_lock (& mused .cyd , 1 );
771850 int r ;
772851 if (a == 0 )
773852 r = open_stuff [t ].open (f );
774853 else
775854 {
776- rw = create_memwriter (f );
777- r = open_stuff [t ].save (rw );
855+ if (t != OD_T_WAVETABLE )
856+ {
857+ rw = create_memwriter (f );
858+ r = open_stuff [t ].save (rw );
859+ }
860+ else
861+ {
862+ r = save_wavetable (f );
863+ }
778864 }
779865
780866 cyd_lock (& mused .cyd , 0 );
@@ -802,4 +888,3 @@ void open_data(void *type, void *action, void *_ret)
802888
803889 change_mode (mused .mode );
804890}
805-
0 commit comments