Mercurial > hg > dmlib
annotate jloadjss.c @ 204:d3a9a3804079
Implement pattern mode 5 in the JMOD jloader.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Sun, 07 Oct 2012 13:15:01 +0300 |
parents | 6bf5220fa47e |
children | 175328b20341 |
rev | line source |
---|---|
0 | 1 /* |
2 * miniJSS - JSSMOD module loader | |
3 * Programmed and designed by Matti 'ccr' Hamalainen | |
4 * (C) Copyright 2007-2009 Tecnic Software productions (TNSP) | |
5 */ | |
6 #include "jssmod.h" | |
7 #include <string.h> | |
8 | |
9 | |
10 #ifdef JM_SUP_PATMODE_ALL | |
11 #define JM_SUP_PATMODE_1 1 | |
12 #define JM_SUP_PATMODE_2 1 | |
13 #define JM_SUP_PATMODE_3 1 | |
14 #define JM_SUP_PATMODE_4 1 | |
15 #define JM_SUP_PATMODE_5 1 | |
16 #endif | |
17 | |
18 | |
19 static BOOL jsGetBufData(Uint8 **buf, size_t *bufLeft, void *data, const size_t dataSize) | |
20 { | |
21 if (*bufLeft >= dataSize) | |
22 { | |
23 memcpy(data, *buf, dataSize); | |
24 *buf += dataSize; | |
25 *bufLeft -= dataSize; | |
26 return TRUE; | |
27 } | |
28 else | |
29 return FALSE; | |
30 } | |
31 | |
32 | |
33 static BOOL jsGetBufByte(Uint8 **buf, size_t *bufLeft, Uint8 *data) | |
34 { | |
35 if (*bufLeft > 0) | |
36 { | |
37 *data = **buf; | |
38 (*buf)++; | |
39 (*bufLeft)--; | |
40 return TRUE; | |
41 } | |
42 else | |
43 return FALSE; | |
44 } | |
45 | |
46 | |
47 #define JSGETBUF(XV, XT) if (!jsGetBufData(buf, bufLeft, XV, sizeof(XT))) return DMERR_OUT_OF_DATA | |
48 #define JSGETBYTE(XV) if (!jsGetBufByte(buf, bufLeft, XV)) return DMERR_OUT_OF_DATA | |
49 | |
50 | |
204
d3a9a3804079
Implement pattern mode 5 in the JMOD jloader.
Matti Hamalainen <ccr@tnsp.org>
parents:
96
diff
changeset
|
51 #if defined(JM_SUP_PATMODE_1) || defined(JM_SUP_PATMODE_3) |
0 | 52 static int jssGetConvertedNote(Uint8 **buf, size_t *bufLeft, JSSNote *note) |
53 { | |
54 Uint8 tmp; | |
55 | |
56 JSGETBYTE(&tmp); | |
57 | |
58 if (tmp == 127) | |
59 note->note = jsetNoteOff; | |
60 else if (tmp == 0) | |
61 note->note = jsetNotSet; | |
62 else | |
63 note->note = tmp - 1; | |
64 | |
65 JSGETBYTE(&tmp); | |
66 note->instrument = (tmp > 0) ? tmp - 1 : jsetNotSet; | |
67 | |
68 JSGETBYTE(&tmp); | |
69 note->volume = (tmp > 0) ? tmp - 1 : jsetNotSet; | |
70 | |
71 JSGETBYTE(&tmp); | |
72 note->effect = (tmp > 0) ? tmp - 1 : jsetNotSet; | |
73 | |
74 JSGETBYTE(&tmp); | |
75 note->param = (tmp == 0 && note->effect == jsetNotSet) ? jsetNotSet : tmp; | |
76 | |
77 return DMERR_OK; | |
78 } | |
79 #endif | |
80 | |
81 | |
204
d3a9a3804079
Implement pattern mode 5 in the JMOD jloader.
Matti Hamalainen <ccr@tnsp.org>
parents:
96
diff
changeset
|
82 #if defined(JM_SUP_PATMODE_2) || defined(JM_SUP_PATMODE_4) |
0 | 83 static int jssGetCompressedNote(Uint8 **buf, size_t *bufLeft, JSSNote *note) |
84 { | |
85 Uint8 packb, tmp; | |
86 | |
87 JSGETBYTE(&packb); | |
88 if (packb & 0x80) | |
89 { | |
90 if (packb & COMP_NOTE) | |
91 { | |
92 JSGETBYTE(&tmp); | |
93 if (tmp == 127) | |
94 note->note = jsetNoteOff; | |
95 else | |
96 note->note = tmp; | |
97 } | |
98 | |
99 if (packb & COMP_INSTRUMENT) | |
100 { | |
101 JSGETBYTE(&tmp); | |
102 note->instrument = tmp; | |
103 } | |
104 | |
105 if (packb & COMP_VOLUME) | |
106 { | |
107 JSGETBYTE(&tmp); | |
108 note->volume = tmp; | |
109 } | |
110 | |
111 if (packb & COMP_EFFECT) | |
112 { | |
113 JSGETBYTE(&tmp); | |
114 note->effect = tmp; | |
115 note->param = 0; | |
116 } | |
117 | |
118 if (packb & COMP_PARAM) | |
119 { | |
120 JSGETBYTE(&tmp); | |
121 note->param = tmp; | |
122 } | |
123 } | |
124 else | |
125 { | |
126 tmp = packb; | |
127 | |
128 if (tmp == 127) | |
129 note->note = jsetNoteOff; | |
130 else if (tmp == 0) | |
131 note->note = jsetNotSet; | |
132 else | |
133 note->note = tmp - 1; | |
134 | |
135 JSGETBYTE(&tmp); | |
136 note->instrument = (tmp > 0) ? tmp - 1 : jsetNotSet; | |
137 | |
138 JSGETBYTE(&tmp); | |
139 note->volume = (tmp > 0) ? tmp - 1 : jsetNotSet; | |
140 | |
141 JSGETBYTE(&tmp); | |
142 note->effect = (tmp > 0) ? tmp - 1 : jsetNotSet; | |
143 | |
144 JSGETBYTE(&tmp); | |
145 note->param = (tmp == 0 && note->effect == jsetNotSet) ? jsetNotSet : tmp; | |
146 } | |
147 | |
148 return DMERR_OK; | |
149 } | |
150 #endif | |
151 | |
152 | |
204
d3a9a3804079
Implement pattern mode 5 in the JMOD jloader.
Matti Hamalainen <ccr@tnsp.org>
parents:
96
diff
changeset
|
153 #ifdef JM_SUP_PATMODE_2 |
0 | 154 static int jssGetPatternCompHoriz(Uint8 *buf, size_t *bufLeft, JSSPattern *pattern) |
155 { | |
156 int row, channel; | |
157 | |
158 assert(buf != NULL); | |
159 assert(pattern != NULL); | |
160 | |
161 for (row = 0; row < pattern->nrows; row++) | |
162 for (channel = 0; channel < pattern->nchannels; channel++) | |
163 { | |
164 JSSNote *note = &pattern->data[(pattern->nchannels * row) + channel]; | |
165 int res = jssGetCompressedNote(&buf, bufLeft, note); | |
166 if (res != DMERR_OK) | |
167 JSSERROR(res, res, "Error uncompressing note on row=%d, chn=%d\n", row, channel); | |
168 } | |
169 | |
170 return DMERR_OK; | |
171 } | |
172 #endif | |
173 | |
174 | |
204
d3a9a3804079
Implement pattern mode 5 in the JMOD jloader.
Matti Hamalainen <ccr@tnsp.org>
parents:
96
diff
changeset
|
175 #ifdef JM_SUP_PATMODE_4 |
0 | 176 static int jssGetPatternCompVert(Uint8 *buf, size_t *bufLeft, JSSPattern *pattern) |
177 { | |
178 int row, channel; | |
179 | |
180 assert(buf != NULL); | |
181 assert(pattern != NULL); | |
182 | |
183 for (channel = 0; channel < pattern->nchannels; channel++) | |
184 for (row = 0; row < pattern->nrows; row++) | |
185 { | |
186 JSSNote *note = &pattern->data[(pattern->nchannels * row) + channel]; | |
187 int res = jssGetCompressedNote(&buf, bufLeft, note); | |
188 if (res != DMERR_OK) | |
189 JSSERROR(res, res, "Error uncompressing note on row=%d, chn=%d\n", row, channel); | |
190 } | |
191 | |
192 return DMERR_OK; | |
193 } | |
194 #endif | |
195 | |
196 | |
204
d3a9a3804079
Implement pattern mode 5 in the JMOD jloader.
Matti Hamalainen <ccr@tnsp.org>
parents:
96
diff
changeset
|
197 #ifdef JM_SUP_PATMODE_1 |
0 | 198 static int jssGetPatternRawHoriz(Uint8 *buf, size_t *bufLeft, JSSPattern *pattern) |
199 { | |
200 int row, channel; | |
201 | |
202 assert(buf != NULL); | |
203 assert(pattern != NULL); | |
204 | |
205 for (row = 0; row < pattern->nrows; row++) | |
206 for (channel = 0; channel < pattern->nchannels; channel++) | |
207 { | |
208 JSSNote *note = &pattern->data[(pattern->nchannels * row) + channel]; | |
209 int res = jssGetConvertedNote(&buf, bufLeft, note); | |
210 if (res != DMERR_OK) | |
211 JSSERROR(res, res, "Error converting note on row=%d, chn=%d\n", row, channel); | |
212 } | |
213 | |
214 return DMERR_OK; | |
215 } | |
216 #endif | |
217 | |
218 | |
204
d3a9a3804079
Implement pattern mode 5 in the JMOD jloader.
Matti Hamalainen <ccr@tnsp.org>
parents:
96
diff
changeset
|
219 #ifdef JM_SUP_PATMODE_3 |
0 | 220 static int jssGetPatternRawVert(Uint8 *buf, size_t *bufLeft, JSSPattern *pattern) |
221 { | |
222 int row, channel; | |
223 | |
224 assert(buf != NULL); | |
225 assert(pattern != NULL); | |
226 | |
227 for (channel = 0; channel < pattern->nchannels; channel++) | |
228 for (row = 0; row < pattern->nrows; row++) | |
229 { | |
230 JSSNote *note = &pattern->data[(pattern->nchannels * row) + channel]; | |
231 int res = jssGetConvertedNote(&buf, bufLeft, note); | |
232 if (res != DMERR_OK) | |
233 JSSERROR(res, res, "Error converting note on row=%d, chn=%d\n", row, channel); | |
234 } | |
235 | |
236 return DMERR_OK; | |
237 } | |
238 #endif | |
239 | |
240 | |
204
d3a9a3804079
Implement pattern mode 5 in the JMOD jloader.
Matti Hamalainen <ccr@tnsp.org>
parents:
96
diff
changeset
|
241 #ifdef JM_SUP_PATMODE_5 |
d3a9a3804079
Implement pattern mode 5 in the JMOD jloader.
Matti Hamalainen <ccr@tnsp.org>
parents:
96
diff
changeset
|
242 |
d3a9a3804079
Implement pattern mode 5 in the JMOD jloader.
Matti Hamalainen <ccr@tnsp.org>
parents:
96
diff
changeset
|
243 #undef JSGETBYTE |
d3a9a3804079
Implement pattern mode 5 in the JMOD jloader.
Matti Hamalainen <ccr@tnsp.org>
parents:
96
diff
changeset
|
244 #define JSGETBYTE(XV) if (!jsGetBufByte(&buf, bufLeft, XV)) return DMERR_OUT_OF_DATA |
d3a9a3804079
Implement pattern mode 5 in the JMOD jloader.
Matti Hamalainen <ccr@tnsp.org>
parents:
96
diff
changeset
|
245 |
d3a9a3804079
Implement pattern mode 5 in the JMOD jloader.
Matti Hamalainen <ccr@tnsp.org>
parents:
96
diff
changeset
|
246 #define JSFOREACHNOTE1 \ |
d3a9a3804079
Implement pattern mode 5 in the JMOD jloader.
Matti Hamalainen <ccr@tnsp.org>
parents:
96
diff
changeset
|
247 for (channel = 0; channel < pattern->nchannels; channel++) \ |
d3a9a3804079
Implement pattern mode 5 in the JMOD jloader.
Matti Hamalainen <ccr@tnsp.org>
parents:
96
diff
changeset
|
248 for (row = 0; row < pattern->nrows; row++) { \ |
d3a9a3804079
Implement pattern mode 5 in the JMOD jloader.
Matti Hamalainen <ccr@tnsp.org>
parents:
96
diff
changeset
|
249 JSSNote *note = pattern->data + (pattern->nchannels * row) + channel; |
d3a9a3804079
Implement pattern mode 5 in the JMOD jloader.
Matti Hamalainen <ccr@tnsp.org>
parents:
96
diff
changeset
|
250 |
d3a9a3804079
Implement pattern mode 5 in the JMOD jloader.
Matti Hamalainen <ccr@tnsp.org>
parents:
96
diff
changeset
|
251 #define JSFOREACHNOTE2 } |
d3a9a3804079
Implement pattern mode 5 in the JMOD jloader.
Matti Hamalainen <ccr@tnsp.org>
parents:
96
diff
changeset
|
252 |
0 | 253 static int jssGetPatternRawVertElem(Uint8 *buf, size_t *bufLeft, JSSPattern *pattern) |
254 { | |
255 int row, channel; | |
204
d3a9a3804079
Implement pattern mode 5 in the JMOD jloader.
Matti Hamalainen <ccr@tnsp.org>
parents:
96
diff
changeset
|
256 Uint8 tmp; |
0 | 257 |
258 assert(buf != NULL); | |
259 assert(pattern != NULL); | |
260 | |
204
d3a9a3804079
Implement pattern mode 5 in the JMOD jloader.
Matti Hamalainen <ccr@tnsp.org>
parents:
96
diff
changeset
|
261 JSFOREACHNOTE1 |
d3a9a3804079
Implement pattern mode 5 in the JMOD jloader.
Matti Hamalainen <ccr@tnsp.org>
parents:
96
diff
changeset
|
262 JSGETBYTE(&tmp); |
d3a9a3804079
Implement pattern mode 5 in the JMOD jloader.
Matti Hamalainen <ccr@tnsp.org>
parents:
96
diff
changeset
|
263 if (tmp == 0) |
d3a9a3804079
Implement pattern mode 5 in the JMOD jloader.
Matti Hamalainen <ccr@tnsp.org>
parents:
96
diff
changeset
|
264 note->note = jsetNotSet; |
d3a9a3804079
Implement pattern mode 5 in the JMOD jloader.
Matti Hamalainen <ccr@tnsp.org>
parents:
96
diff
changeset
|
265 else if (tmp == 127) |
d3a9a3804079
Implement pattern mode 5 in the JMOD jloader.
Matti Hamalainen <ccr@tnsp.org>
parents:
96
diff
changeset
|
266 note->note == jsetNoteOff; |
d3a9a3804079
Implement pattern mode 5 in the JMOD jloader.
Matti Hamalainen <ccr@tnsp.org>
parents:
96
diff
changeset
|
267 else |
d3a9a3804079
Implement pattern mode 5 in the JMOD jloader.
Matti Hamalainen <ccr@tnsp.org>
parents:
96
diff
changeset
|
268 note->note = tmp - 1; |
d3a9a3804079
Implement pattern mode 5 in the JMOD jloader.
Matti Hamalainen <ccr@tnsp.org>
parents:
96
diff
changeset
|
269 JSFOREACHNOTE2 |
d3a9a3804079
Implement pattern mode 5 in the JMOD jloader.
Matti Hamalainen <ccr@tnsp.org>
parents:
96
diff
changeset
|
270 |
d3a9a3804079
Implement pattern mode 5 in the JMOD jloader.
Matti Hamalainen <ccr@tnsp.org>
parents:
96
diff
changeset
|
271 JSFOREACHNOTE1 |
d3a9a3804079
Implement pattern mode 5 in the JMOD jloader.
Matti Hamalainen <ccr@tnsp.org>
parents:
96
diff
changeset
|
272 JSGETBYTE(&tmp); |
d3a9a3804079
Implement pattern mode 5 in the JMOD jloader.
Matti Hamalainen <ccr@tnsp.org>
parents:
96
diff
changeset
|
273 note->instrument = tmp; |
d3a9a3804079
Implement pattern mode 5 in the JMOD jloader.
Matti Hamalainen <ccr@tnsp.org>
parents:
96
diff
changeset
|
274 JSFOREACHNOTE2 |
d3a9a3804079
Implement pattern mode 5 in the JMOD jloader.
Matti Hamalainen <ccr@tnsp.org>
parents:
96
diff
changeset
|
275 |
d3a9a3804079
Implement pattern mode 5 in the JMOD jloader.
Matti Hamalainen <ccr@tnsp.org>
parents:
96
diff
changeset
|
276 JSFOREACHNOTE1 |
d3a9a3804079
Implement pattern mode 5 in the JMOD jloader.
Matti Hamalainen <ccr@tnsp.org>
parents:
96
diff
changeset
|
277 JSGETBYTE(&tmp); |
d3a9a3804079
Implement pattern mode 5 in the JMOD jloader.
Matti Hamalainen <ccr@tnsp.org>
parents:
96
diff
changeset
|
278 note->volume = tmp; |
d3a9a3804079
Implement pattern mode 5 in the JMOD jloader.
Matti Hamalainen <ccr@tnsp.org>
parents:
96
diff
changeset
|
279 JSFOREACHNOTE2 |
d3a9a3804079
Implement pattern mode 5 in the JMOD jloader.
Matti Hamalainen <ccr@tnsp.org>
parents:
96
diff
changeset
|
280 |
d3a9a3804079
Implement pattern mode 5 in the JMOD jloader.
Matti Hamalainen <ccr@tnsp.org>
parents:
96
diff
changeset
|
281 JSFOREACHNOTE1 |
d3a9a3804079
Implement pattern mode 5 in the JMOD jloader.
Matti Hamalainen <ccr@tnsp.org>
parents:
96
diff
changeset
|
282 JSGETBYTE(&tmp); |
d3a9a3804079
Implement pattern mode 5 in the JMOD jloader.
Matti Hamalainen <ccr@tnsp.org>
parents:
96
diff
changeset
|
283 note->effect = tmp; |
d3a9a3804079
Implement pattern mode 5 in the JMOD jloader.
Matti Hamalainen <ccr@tnsp.org>
parents:
96
diff
changeset
|
284 JSFOREACHNOTE2 |
d3a9a3804079
Implement pattern mode 5 in the JMOD jloader.
Matti Hamalainen <ccr@tnsp.org>
parents:
96
diff
changeset
|
285 |
d3a9a3804079
Implement pattern mode 5 in the JMOD jloader.
Matti Hamalainen <ccr@tnsp.org>
parents:
96
diff
changeset
|
286 JSFOREACHNOTE1 |
d3a9a3804079
Implement pattern mode 5 in the JMOD jloader.
Matti Hamalainen <ccr@tnsp.org>
parents:
96
diff
changeset
|
287 JSGETBYTE(&tmp); |
d3a9a3804079
Implement pattern mode 5 in the JMOD jloader.
Matti Hamalainen <ccr@tnsp.org>
parents:
96
diff
changeset
|
288 note->param = tmp; |
d3a9a3804079
Implement pattern mode 5 in the JMOD jloader.
Matti Hamalainen <ccr@tnsp.org>
parents:
96
diff
changeset
|
289 JSFOREACHNOTE2 |
d3a9a3804079
Implement pattern mode 5 in the JMOD jloader.
Matti Hamalainen <ccr@tnsp.org>
parents:
96
diff
changeset
|
290 |
0 | 291 return DMERR_OK; |
292 } | |
293 #endif | |
294 | |
295 | |
296 #undef JSGETBUF | |
297 #undef JSGETBYTE | |
298 #define JSGETBUF(XV, XT) do { \ | |
299 if (!jsGetBufData(&buf, &bufLeft, XV, sizeof(XT))) \ | |
300 JSSERROR(DMERR_OUT_OF_DATA, DMERR_OUT_OF_DATA, \ | |
301 "Out of data at getting " # XT " (%d bytes)\n", sizeof(XT)); \ | |
302 } while (0) | |
303 #define JSGETBYTE(XV) if (!jsGetBufByte(&buf, &bufLeft, XV)) return DMERR_OUT_OF_DATA | |
304 | |
305 | |
306 #ifdef JM_SUP_EXT_INSTR | |
307 static void jssCopyEnvelope(JSSEnvelope *e, JSSMODEnvelope *je) | |
308 { | |
309 int i; | |
310 | |
311 e->flags = je->flags; | |
312 e->npoints = je->npoints; | |
313 e->sustain = je->sustain; | |
314 e->loopS = je->loopS; | |
315 e->loopE = je->loopE; | |
316 | |
317 for (i = 0; i < je->npoints; i++) | |
318 { | |
319 e->points[i].frame = je->points[i].frame; | |
320 e->points[i].value = je->points[i].value; | |
321 } | |
322 } | |
323 #endif | |
324 | |
325 | |
326 int jssLoadJSSMOD(Uint8 *bufStart, const size_t bufSize, JSSModule **ppModule) | |
327 { | |
328 JSSModule *module; | |
329 JSSMODHeader jssH; | |
330 Uint8 *buf = bufStart; | |
331 size_t bufLeft = bufSize; | |
332 int index; | |
333 | |
334 assert(ppModule != NULL); | |
335 assert(bufStart != NULL); | |
336 *ppModule = NULL; | |
337 | |
338 // Check the JSSMOD header | |
96
6bf5220fa47e
Urgh .. use memset to silence some bogus GCC warnings about using
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
339 memset(&jssH, 0, sizeof(jssH)); |
0 | 340 JSGETBUF(&jssH, JSSMODHeader); |
341 | |
342 if (memcmp(jssH.idMagic, "JM", 2) != 0) | |
343 { | |
344 JSSERROR(DMERR_INVALID_DATA, DMERR_INVALID_DATA, | |
345 "Not a valid JSSMOD file, header signature missing!\n"); | |
346 } | |
347 | |
348 if (jssH.idVersion != JSSMOD_VERSION) | |
349 { | |
350 JSSERROR(DMERR_VERSION, DMERR_VERSION, | |
351 "Unsupported version of JSSMOD 0x%4x, this version only supports 0x%4x!\n", | |
352 jssH.idVersion, JSSMOD_VERSION); | |
353 } | |
354 | |
355 // Allocate the module | |
356 module = jssAllocateModule(); | |
357 if (module == NULL) | |
358 { | |
359 JSSERROR(DMERR_MALLOC, DMERR_MALLOC, | |
360 "Could not allocate memory for module structure.\n"); | |
361 } | |
362 *ppModule = module; | |
363 | |
364 // Copy header information | |
365 module->norders = jssH.norders; | |
366 module->npatterns = jssH.npatterns; | |
367 module->nchannels = jssH.nchannels; | |
368 module->nextInstruments = jssH.nextInstruments; | |
369 module->ninstruments = jssH.ninstruments; | |
370 module->defFlags = jssH.defFlags; | |
371 module->intVersion = jssH.intVersion; | |
372 module->defRestartPos = jssH.defRestartPos; | |
373 module->defSpeed = jssH.defSpeed; | |
374 module->defTempo = jssH.defTempo; | |
375 | |
376 // Get the orders list | |
377 for (index = 0; index < module->norders; index++) | |
378 { | |
379 Sint16 order; | |
380 JSGETBUF(&order, Sint16); | |
381 module->orderList[index] = order; | |
382 } | |
383 | |
384 // Parse the patterns | |
385 for (index = 0; index < module->npatterns; index++) | |
386 { | |
387 JSSMODPattern jssP; | |
388 int result = DMERR_INVALID_DATA; | |
389 size_t bufSize; | |
390 | |
391 // Get header and check size | |
96
6bf5220fa47e
Urgh .. use memset to silence some bogus GCC warnings about using
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
392 memset(&jssP, 0, sizeof(jssP)); |
0 | 393 JSGETBUF(&jssP, JSSMODPattern); |
394 bufSize = jssP.size; | |
395 if (bufLeft < jssP.size) | |
396 { | |
397 JSSERROR(DMERR_OUT_OF_DATA, DMERR_OUT_OF_DATA, | |
398 "Out of data for pattern #%d.\n", index); | |
399 } | |
400 | |
401 // Allocate pattern | |
402 module->patterns[index] = jssAllocatePattern(jssP.nrows, module->nchannels); | |
403 if (module->patterns[index] == NULL) | |
404 { | |
405 JSSERROR(DMERR_MALLOC, DMERR_MALLOC, | |
406 "Could not allocate memory for pattern #%d.\n", index); | |
407 } | |
408 | |
409 // Get pattern data | |
410 switch (jssH.patMode) | |
411 { | |
412 #ifdef JM_SUP_PATMODE_1 | |
413 case PATMODE_RAW_HORIZ: | |
414 result = jssGetPatternRawHoriz(buf, &bufSize, module->patterns[index]); | |
415 break; | |
416 #endif | |
417 #ifdef JM_SUP_PATMODE_2 | |
418 case PATMODE_COMP_HORIZ: | |
419 result = jssGetPatternCompHoriz(buf, &bufSize, module->patterns[index]); | |
420 break; | |
421 #endif | |
422 #ifdef JM_SUP_PATMODE_3 | |
423 case PATMODE_RAW_VERT: | |
424 result = jssGetPatternRawVert(buf, &bufSize, module->patterns[index]); | |
425 break; | |
426 #endif | |
427 #ifdef JM_SUP_PATMODE_4 | |
428 case PATMODE_COMP_VERT: | |
429 result = jssGetPatternCompVert(buf, &bufSize, module->patterns[index]); | |
430 break; | |
431 #endif | |
432 #ifdef JM_SUP_PATMODE_5 | |
433 case PATMODE_RAW_ELEM: | |
434 result = jssGetPatternRawVertElem(buf, &bufSize, module->patterns[index]); | |
435 break; | |
436 #endif | |
437 default: | |
438 JSSERROR(DMERR_INVALID_DATA, DMERR_INVALID_DATA, | |
439 "Unsupported pattern mode %d. Check compilation options.", jssH.patMode); | |
440 break; | |
441 } | |
442 | |
443 if (bufSize > 0) | |
444 { | |
445 JSSWARNING(DMERR_EXTRA_DATA, DMERR_EXTRA_DATA, | |
446 "Unparsed data after pattern (%d bytes), possibly broken file.\n", bufSize); | |
447 } | |
448 | |
449 if (result != DMERR_OK) | |
450 { | |
451 JSSERROR(result, result, "Error in unpacking pattern #%i data\n", index); | |
452 } | |
453 | |
454 buf += jssP.size; | |
455 bufLeft -= jssP.size; | |
456 } | |
457 | |
458 #ifdef JM_SUP_EXT_INSTR | |
459 // Read extended instruments | |
460 for (index = 0; index < module->nextInstruments; index++) | |
461 { | |
462 JSSMODExtInstrument jssE; | |
463 JSSExtInstrument *einst; | |
464 int i; | |
465 | |
96
6bf5220fa47e
Urgh .. use memset to silence some bogus GCC warnings about using
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
466 memset(&jssE, 0, sizeof(jssE)); |
0 | 467 JSGETBUF(&jssE, JSSMODExtInstrument); |
468 | |
469 if ((einst = jssAllocateExtInstrument()) == NULL) | |
470 { | |
471 JSSERROR(DMERR_MALLOC, DMERR_MALLOC, | |
472 "Could not allocate extended instrument structure #%i\n", index); | |
473 } | |
474 | |
475 module->extInstruments[index] = einst; | |
476 | |
477 einst->nsamples = jssE.nsamples; | |
478 einst->vibratoType = jssE.vibratoType; | |
479 einst->vibratoSweep = jssE.vibratoSweep; | |
480 einst->vibratoDepth = jssE.vibratoDepth; | |
481 einst->vibratoRate = jssE.vibratoRate; | |
482 einst->fadeOut = jssE.fadeOut; | |
483 | |
484 for (i = 0; i < jsetNNotes; i++) | |
485 { | |
486 int snum = jssE.sNumForNotes[i]; | |
487 einst->sNumForNotes[i] = (snum > 0) ? snum : jsetNotSet; | |
488 } | |
489 | |
490 jssCopyEnvelope(&(einst->volumeEnv), &jssE.volumeEnv); | |
491 jssCopyEnvelope(&(einst->panningEnv), &jssE.panningEnv); | |
492 } | |
493 | |
494 #ifdef JM_SUP_INSTR | |
495 // Read sample instrument headers | |
496 for (index = 0; index < module->ninstruments; index++) | |
497 { | |
498 JSSMODInstrument jssI; | |
499 JSSInstrument *inst; | |
500 | |
96
6bf5220fa47e
Urgh .. use memset to silence some bogus GCC warnings about using
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
501 memset(&jssI, 0, sizeof(jssI)); |
0 | 502 JSGETBUF(&jssI, JSSMODInstrument); |
503 | |
504 if ((inst = jssAllocateInstrument()) == NULL) | |
505 { | |
506 JSSERROR(DMERR_MALLOC, DMERR_MALLOC, | |
507 "Could not allocate instrument structure #%i\n", index); | |
508 } | |
509 | |
510 module->instruments[index] = inst; | |
511 | |
512 inst->size = jssI.size; | |
513 inst->loopS = jssI.loopS; | |
514 inst->loopE = jssI.loopE; | |
515 inst->volume = jssI.volume; | |
516 inst->flags = jssI.flags; | |
517 inst->C4BaseSpeed = jssI.C4BaseSpeed; | |
518 inst->ERelNote = jssI.ERelNote; | |
519 inst->EFineTune = jssI.EFineTune; | |
520 inst->EPanning = jssI.EPanning; | |
521 inst->hasData = jssI.hasData; | |
522 inst->convFlags = jssI.convFlags; | |
523 } | |
524 | |
525 #ifdef JM_SUP_SAMPLES | |
526 // Read sample data | |
527 for (index = 0; index < module->ninstruments; index++) | |
528 { | |
529 JSSInstrument *inst = module->instruments[index]; | |
530 | |
531 if (inst && inst->hasData) | |
532 { | |
533 size_t sz; | |
534 | |
535 // Calculate data size | |
536 if (inst->flags & jsf16bit) | |
537 sz = inst->size * sizeof(Uint16); | |
538 else | |
539 sz = inst->size * sizeof(Uint8); | |
540 | |
541 // Check if we can get as much? | |
542 if (bufLeft < sz) | |
543 { | |
544 JSSERROR(DMERR_OUT_OF_DATA, DMERR_OUT_OF_DATA, | |
545 "Out of data for instrument sample #%d (%d < %d)\n", | |
546 index, bufLeft, sz); | |
547 } | |
548 | |
549 // Allocate | |
550 if ((inst->data = dmMalloc(sz)) == NULL) | |
551 { | |
552 JSSERROR(DMERR_MALLOC, DMERR_MALLOC, | |
553 "Could not allocate sample data #%d\n", index); | |
554 } | |
555 | |
556 // Copy data | |
557 memcpy(inst->data, buf, sz); | |
558 buf += sz; | |
559 bufLeft -= sz; | |
560 | |
561 // Convert, if needed | |
562 if (inst->flags & jsf16bit) | |
563 jssDecodeSample16(inst->data, inst->size, inst->convFlags); | |
564 else | |
565 jssDecodeSample8(inst->data, inst->size, inst->convFlags); | |
566 } | |
567 } | |
568 #else | |
569 #warning Not including JSSMOD sample loading! | |
570 #endif // JM_SUP_SAMPLES | |
571 #else | |
572 #warning Not including JSSMOD instrument loading! | |
573 #endif // JM_SUP_INSTR | |
574 #else | |
575 #warning Not including JSSMOD ext.instrument loading! | |
576 #endif // JM_SUP_EXT_INSTR | |
577 | |
578 return DMERR_OK; | |
579 } |