1 /*
2  * Schism Tracker - a cross-platform Impulse Tracker clone
3  * copyright (c) 2003-2005 Storlek <storlek@rigelseven.com>
4  * copyright (c) 2005-2008 Mrs. Brisby <mrs.brisby@nimh.org>
5  * copyright (c) 2009 Storlek & Mrs. Brisby
6  * copyright (c) 2010-2012 Storlek
7  * URL: http://schismtracker.org/
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22  */
23 
24 #ifndef FMT_H
25 #define FMT_H
26 
27 #include <stdint.h>
28 #include "dmoz.h"
29 #include "slurp.h"
30 #include "util.h"
31 
32 #include "disko.h"
33 
34 #include "sndfile.h"
35 
36 /* --------------------------------------------------------------------------------------------------------- */
37 /* module loaders */
38 
39 /* flags to skip loading some data (mainly for scraping titles)
40 this is only a suggestion in order to speed loading; don't be surprised if the loader ignores these */
41 #define LOAD_NOSAMPLES  1
42 #define LOAD_NOPATTERNS 2
43 
44 /* return codes for module loaders */
45 enum {
46 	LOAD_SUCCESS,           /* all's well */
47 	LOAD_UNSUPPORTED,       /* wrong file type for the loader */
48 	LOAD_FILE_ERROR,        /* couldn't read the file; check errno */
49 	LOAD_FORMAT_ERROR,      /* it appears to be the correct type, but there's something wrong */
50 };
51 
52 /* return codes for modules savers */
53 enum {
54 	SAVE_SUCCESS,           /* all's well */
55 	SAVE_FILE_ERROR,        /* couldn't write the file; check errno */
56 	SAVE_INTERNAL_ERROR,    /* something unrelated to disk i/o */
57 };
58 
59 /* --------------------------------------------------------------------------------------------------------- */
60 
61 #define PROTO_READ_INFO         (dmoz_file_t *file, const uint8_t *data, size_t length)
62 #define PROTO_LOAD_SONG         (song_t *song, slurp_t *fp, unsigned int lflags)
63 #define PROTO_SAVE_SONG         (disko_t *fp, song_t *song)
64 #define PROTO_LOAD_SAMPLE       (const uint8_t *data, size_t length, song_sample_t *smp)
65 #define PROTO_SAVE_SAMPLE       (disko_t *fp, song_sample_t *smp)
66 #define PROTO_LOAD_INSTRUMENT   (const uint8_t *data, size_t length, int slot)
67 #define PROTO_EXPORT_HEAD       (disko_t *fp, int bits, int channels, int rate)
68 #define PROTO_EXPORT_SILENCE    (disko_t *fp, long bytes)
69 #define PROTO_EXPORT_BODY       (disko_t *fp, const uint8_t *data, size_t length)
70 #define PROTO_EXPORT_TAIL       (disko_t *fp)
71 
72 typedef int (*fmt_read_info_func)       PROTO_READ_INFO;
73 typedef int (*fmt_load_song_func)       PROTO_LOAD_SONG;
74 typedef int (*fmt_save_song_func)       PROTO_SAVE_SONG;
75 typedef int (*fmt_load_sample_func)     PROTO_LOAD_SAMPLE;
76 typedef int (*fmt_save_sample_func)     PROTO_SAVE_SAMPLE;
77 typedef int (*fmt_load_instrument_func) PROTO_LOAD_INSTRUMENT;
78 typedef int (*fmt_export_head_func)     PROTO_EXPORT_HEAD;
79 typedef int (*fmt_export_silence_func)  PROTO_EXPORT_SILENCE;
80 typedef int (*fmt_export_body_func)     PROTO_EXPORT_BODY;
81 typedef int (*fmt_export_tail_func)     PROTO_EXPORT_TAIL;
82 
83 #define READ_INFO(t)            int fmt_##t##_read_info         PROTO_READ_INFO;
84 #define LOAD_SONG(t)            int fmt_##t##_load_song         PROTO_LOAD_SONG;
85 #define SAVE_SONG(t)            int fmt_##t##_save_song         PROTO_SAVE_SONG;
86 #define LOAD_SAMPLE(t)          int fmt_##t##_load_sample       PROTO_LOAD_SAMPLE;
87 #define SAVE_SAMPLE(t)          int fmt_##t##_save_sample       PROTO_SAVE_SAMPLE;
88 #define LOAD_INSTRUMENT(t)      int fmt_##t##_load_instrument   PROTO_LOAD_INSTRUMENT;
89 #define EXPORT(t)               int fmt_##t##_export_head       PROTO_EXPORT_HEAD; \
90 				int fmt_##t##_export_silence    PROTO_EXPORT_SILENCE; \
91 				int fmt_##t##_export_body       PROTO_EXPORT_BODY; \
92 				int fmt_##t##_export_tail       PROTO_EXPORT_TAIL;
93 
94 #include "fmt-types.h"
95 
96 /* --------------------------------------------------------------------------------------------------------- */
97 
98 struct save_format {
99 	const char *label; // label for the button on the save page
100 	const char *name; // long name of format
101 	const char *ext; // no dot
102 	union {
103 		fmt_save_song_func save_song;
104 		fmt_save_sample_func save_sample;
105 		struct {
106 			fmt_export_head_func head;
107 			fmt_export_silence_func silence;
108 			fmt_export_body_func body;
109 			fmt_export_tail_func tail;
110 			int multi;
111 		} export;
112 	} f;
113 };
114 
115 extern const struct save_format song_save_formats[];
116 extern const struct save_format song_export_formats[];
117 extern const struct save_format sample_save_formats[];
118 
119 /* --------------------------------------------------------------------------------------------------------- */
120 struct instrumentloader {
121 	song_instrument_t *inst;
122 	int sample_map[MAX_SAMPLES];
123 	int basex, slot, expect_samples;
124 };
125 song_instrument_t *instrument_loader_init(struct instrumentloader *ii, int slot);
126 int instrument_loader_abort(struct instrumentloader *ii);
127 int instrument_loader_sample(struct instrumentloader *ii, int slot);
128 
129 /* --------------------------------------------------------------------------------------------------------- */
130 
131 uint32_t it_decompress8(void *dest, uint32_t len, const void *file, uint32_t filelen, int it215, int channels);
132 uint32_t it_decompress16(void *dest, uint32_t len, const void *file, uint32_t filelen, int it215, int channels);
133 
134 uint16_t mdl_read_bits(uint32_t *bitbuf, uint32_t *bitnum, uint8_t **ibuf, int8_t n);
135 
136 /* --------------------------------------------------------------------------------------------------------- */
137 
138 /* shared by the .it, .its, and .iti saving functions */
139 void save_its_header(disko_t *fp, song_sample_t *smp);
140 int load_its_sample(const uint8_t *header, const uint8_t *data, size_t length, song_sample_t *smp);
141 
142 /* --------------------------------------------------------------------------------------------------------- */
143 // other misc functions...
144 
145 /* effect_weight[FX_something] => how "important" the effect is. */
146 extern const uint8_t effect_weight[];
147 
148 /* Shuffle the effect and volume-effect values around.
149 Note: this does NOT convert between volume and 'normal' effects, it only exchanges them.
150 (This function is most useful in conjunction with convert_voleffect in order to try to
151 cram ten pounds of crap into a five pound container) */
152 void swap_effects(song_note_t *note);
153 
154 /* Convert volume column data from FX_* to VOLFX_*, if possible.
155 Return: 1 = it was properly converted, 0 = couldn't do so without loss of information. */
156 int convert_voleffect(uint8_t *effect, uint8_t *param, int force);
157 #define convert_voleffect_of(note,force) convert_voleffect(&((note)->voleffect), &((note)->volparam), (force))
158 
159 // load a .mod-style 4-byte packed note
160 void mod_import_note(const uint8_t p[4], song_note_t *note);
161 
162 // Read a message with fixed-size line lengths
163 void read_lined_message(char *msg, slurp_t *fp, int len, int linelen);
164 
165 
166 // get L-R-R-L panning value from a (zero-based!) channel number
167 #define PROTRACKER_PANNING(n) (((((n) + 1) >> 1) & 1) * 256)
168 
169 // convert .mod finetune byte value to c5speed
170 #define MOD_FINETUNE(b) (finetune_table[((b) & 0xf) ^ 8])
171 
172 /* --------------------------------------------------------------------------------------------------------- */
173 
174 #endif /* ! FMT_H */
175 
176