comparison minijss/jloadjss.c @ 777:ed60a7ee3ebb

Change JSSMOD loader to use DMResources.
author Matti Hamalainen <ccr@tnsp.org>
date Fri, 24 May 2013 01:19:11 +0300
parents c430112449a7
children 97ecc0a9c21f
comparison
equal deleted inserted replaced
776:9acebca96dcc 777:ed60a7ee3ebb
14 # define JM_SUP_PATMODE_4 1 14 # define JM_SUP_PATMODE_4 1
15 # define JM_SUP_PATMODE_5 1 15 # define JM_SUP_PATMODE_5 1
16 #endif 16 #endif
17 17
18 18
19 static BOOL jsGetBufData(Uint8 **buf, size_t *bufLeft, void *data, const size_t dataSize) 19 #define JSGETBUF(XV, XT) if (!dmf_read_str(inFile, XV, sizeof(XT))) return DMERR_OUT_OF_DATA
20 { 20 #define JSGETBYTE(XV) if (!dmf_read_byte(inFile, XV)) return DMERR_OUT_OF_DATA
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 21
50 22
51 #if defined(JM_SUP_PATMODE_1) || defined(JM_SUP_PATMODE_3) 23 #if defined(JM_SUP_PATMODE_1) || defined(JM_SUP_PATMODE_3)
52 static int jssGetConvertedNote(Uint8 **buf, size_t *bufLeft, JSSNote *note) 24 static int jssGetConvertedNote(DMResource *inFile, JSSNote *note)
53 { 25 {
54 Uint8 tmp; 26 Uint8 tmp;
55 27
56 JSGETBYTE(&tmp); 28 JSGETBYTE(&tmp);
57 29
78 } 50 }
79 #endif 51 #endif
80 52
81 53
82 #if defined(JM_SUP_PATMODE_2) || defined(JM_SUP_PATMODE_4) 54 #if defined(JM_SUP_PATMODE_2) || defined(JM_SUP_PATMODE_4)
83 static int jssGetCompressedNote(Uint8 **buf, size_t *bufLeft, JSSNote *note) 55 static int jssGetCompressedNote(DMResource *inFile, JSSNote *note)
84 { 56 {
85 Uint8 packb, tmp; 57 Uint8 packb, tmp;
86 58
87 JSGETBYTE(&packb); 59 JSGETBYTE(&packb);
88 if (packb & 0x80) 60 if (packb & 0x80)
149 } 121 }
150 #endif 122 #endif
151 123
152 124
153 #ifdef JM_SUP_PATMODE_2 125 #ifdef JM_SUP_PATMODE_2
154 static int jssGetPatternCompHoriz(Uint8 *buf, size_t *bufLeft, JSSPattern *pattern) 126 static int jssGetPatternCompHoriz(DMResource *inFile, JSSPattern *pattern)
155 { 127 {
156 int row, channel; 128 int row, channel;
157 129
158 assert(buf != NULL); 130 assert(buf != NULL);
159 assert(pattern != NULL); 131 assert(pattern != NULL);
160 132
161 for (row = 0; row < pattern->nrows; row++) 133 for (row = 0; row < pattern->nrows; row++)
162 for (channel = 0; channel < pattern->nchannels; channel++) 134 for (channel = 0; channel < pattern->nchannels; channel++)
163 { 135 {
164 JSSNote *note = &pattern->data[(pattern->nchannels * row) + channel]; 136 JSSNote *note = &pattern->data[(pattern->nchannels * row) + channel];
165 int res = jssGetCompressedNote(&buf, bufLeft, note); 137 int res = jssGetCompressedNote(inFile, note);
166 if (res != DMERR_OK) 138 if (res != DMERR_OK)
167 JSSERROR(res, res, "Error uncompressing note on row=%d, chn=%d\n", row, channel); 139 JSSERROR(res, res, "Error uncompressing note on row=%d, chn=%d\n", row, channel);
168 } 140 }
169 141
170 return DMERR_OK; 142 return DMERR_OK;
171 } 143 }
172 #endif 144 #endif
173 145
174 146
175 #ifdef JM_SUP_PATMODE_4 147 #ifdef JM_SUP_PATMODE_4
176 static int jssGetPatternCompVert(Uint8 *buf, size_t *bufLeft, JSSPattern *pattern) 148 static int jssGetPatternCompVert(DMResource *inFile, JSSPattern *pattern)
177 { 149 {
178 int row, channel; 150 int row, channel;
179 151
180 assert(buf != NULL); 152 assert(buf != NULL);
181 assert(pattern != NULL); 153 assert(pattern != NULL);
182 154
183 for (channel = 0; channel < pattern->nchannels; channel++) 155 for (channel = 0; channel < pattern->nchannels; channel++)
184 for (row = 0; row < pattern->nrows; row++) 156 for (row = 0; row < pattern->nrows; row++)
185 { 157 {
186 JSSNote *note = &pattern->data[(pattern->nchannels * row) + channel]; 158 JSSNote *note = &pattern->data[(pattern->nchannels * row) + channel];
187 int res = jssGetCompressedNote(&buf, bufLeft, note); 159 int res = jssGetCompressedNote(inFile, note);
188 if (res != DMERR_OK) 160 if (res != DMERR_OK)
189 JSSERROR(res, res, "Error uncompressing note on row=%d, chn=%d\n", row, channel); 161 JSSERROR(res, res, "Error uncompressing note on row=%d, chn=%d\n", row, channel);
190 } 162 }
191 163
192 return DMERR_OK; 164 return DMERR_OK;
193 } 165 }
194 #endif 166 #endif
195 167
196 168
197 #ifdef JM_SUP_PATMODE_1 169 #ifdef JM_SUP_PATMODE_1
198 static int jssGetPatternRawHoriz(Uint8 *buf, size_t *bufLeft, JSSPattern *pattern) 170 static int jssGetPatternRawHoriz(DMResource *inFile, JSSPattern *pattern)
199 { 171 {
200 int row, channel; 172 int row, channel;
201 173
202 assert(buf != NULL); 174 assert(buf != NULL);
203 assert(pattern != NULL); 175 assert(pattern != NULL);
204 176
205 for (row = 0; row < pattern->nrows; row++) 177 for (row = 0; row < pattern->nrows; row++)
206 for (channel = 0; channel < pattern->nchannels; channel++) 178 for (channel = 0; channel < pattern->nchannels; channel++)
207 { 179 {
208 JSSNote *note = &pattern->data[(pattern->nchannels * row) + channel]; 180 JSSNote *note = &pattern->data[(pattern->nchannels * row) + channel];
209 int res = jssGetConvertedNote(&buf, bufLeft, note); 181 int res = jssGetConvertedNote(inFile, note);
210 if (res != DMERR_OK) 182 if (res != DMERR_OK)
211 JSSERROR(res, res, "Error converting note on row=%d, chn=%d\n", row, channel); 183 JSSERROR(res, res, "Error converting note on row=%d, chn=%d\n", row, channel);
212 } 184 }
213 185
214 return DMERR_OK; 186 return DMERR_OK;
215 } 187 }
216 #endif 188 #endif
217 189
218 190
219 #ifdef JM_SUP_PATMODE_3 191 #ifdef JM_SUP_PATMODE_3
220 static int jssGetPatternRawVert(Uint8 *buf, size_t *bufLeft, JSSPattern *pattern) 192 static int jssGetPatternRawVert(DMResource *inFile, JSSPattern *pattern)
221 { 193 {
222 int row, channel; 194 int row, channel;
223 195
224 assert(buf != NULL); 196 assert(buf != NULL);
225 assert(pattern != NULL); 197 assert(pattern != NULL);
226 198
227 for (channel = 0; channel < pattern->nchannels; channel++) 199 for (channel = 0; channel < pattern->nchannels; channel++)
228 for (row = 0; row < pattern->nrows; row++) 200 for (row = 0; row < pattern->nrows; row++)
229 { 201 {
230 JSSNote *note = &pattern->data[(pattern->nchannels * row) + channel]; 202 JSSNote *note = &pattern->data[(pattern->nchannels * row) + channel];
231 int res = jssGetConvertedNote(&buf, bufLeft, note); 203 int res = jssGetConvertedNote(inFile, note);
232 if (res != DMERR_OK) 204 if (res != DMERR_OK)
233 JSSERROR(res, res, "Error converting note on row=%d, chn=%d\n", row, channel); 205 JSSERROR(res, res, "Error converting note on row=%d, chn=%d\n", row, channel);
234 } 206 }
235 207
236 return DMERR_OK; 208 return DMERR_OK;
239 211
240 212
241 #ifdef JM_SUP_PATMODE_5 213 #ifdef JM_SUP_PATMODE_5
242 214
243 #undef JSGETBYTE 215 #undef JSGETBYTE
244 #define JSGETBYTE(XV) if (!jsGetBufByte(&buf, bufLeft, XV)) return DMERR_OUT_OF_DATA 216 #define JSGETBYTE(XV) if (!dmf_read_byte(inFile, XV)) return DMERR_OUT_OF_DATA
245 217
246 #define JSFOREACHNOTE1 \ 218 #define JSFOREACHNOTE1 \
247 for (channel = 0; channel < pattern->nchannels; channel++) \ 219 for (channel = 0; channel < pattern->nchannels; channel++) \
248 for (row = 0; row < pattern->nrows; row++) { \ 220 for (row = 0; row < pattern->nrows; row++) { \
249 JSSNote *note = pattern->data + (pattern->nchannels * row) + channel; 221 JSSNote *note = pattern->data + (pattern->nchannels * row) + channel;
250 222
251 #define JSFOREACHNOTE2 } 223 #define JSFOREACHNOTE2 }
252 224
253 static int jssGetPatternRawVertElem(Uint8 *buf, size_t *bufLeft, JSSPattern *pattern) 225 static int jssGetPatternRawVertElem(DMResource *inFile, JSSPattern *pattern)
254 { 226 {
255 int row, channel; 227 int row, channel;
256 Uint8 tmp; 228 Uint8 tmp;
257 229
258 assert(buf != NULL); 230 assert(buf != NULL);
294 266
295 267
296 #undef JSGETBUF 268 #undef JSGETBUF
297 #undef JSGETBYTE 269 #undef JSGETBYTE
298 #define JSGETBUF(XV, XT) do { \ 270 #define JSGETBUF(XV, XT) do { \
299 if (!jsGetBufData(&buf, &bufLeft, XV, sizeof(XT))) \ 271 if (!dmf_read_str(inFile, XV, sizeof(XT))) \
300 JSSERROR(DMERR_OUT_OF_DATA, DMERR_OUT_OF_DATA, \ 272 JSSERROR(DMERR_OUT_OF_DATA, DMERR_OUT_OF_DATA, \
301 "Out of data at getting " # XT " (%d bytes)\n", sizeof(XT)); \ 273 "Out of data at getting " # XT " (%d bytes)\n", sizeof(XT)); \
302 } while (0) 274 } while (0)
303 #define JSGETBYTE(XV) if (!jsGetBufByte(&buf, &bufLeft, XV)) return DMERR_OUT_OF_DATA 275 #define JSGETBYTE(XV) if (!dmf_read_byte(inFile, XV)) return DMERR_OUT_OF_DATA
304 276
305 277
306 #ifdef JM_SUP_EXT_INSTR 278 #ifdef JM_SUP_EXT_INSTR
307 static void jssCopyEnvelope(JSSEnvelope *e, JSSMODEnvelope *je) 279 static void jssCopyEnvelope(JSSEnvelope *e, JSSMODEnvelope *je)
308 { 280 {
321 } 293 }
322 } 294 }
323 #endif 295 #endif
324 296
325 297
326 int jssLoadJSSMOD(Uint8 *bufStart, const size_t bufSize, JSSModule **ppModule) 298 int jssLoadJSSMOD(DMResource *inFile, JSSModule **ppModule)
327 { 299 {
328 JSSModule *module; 300 JSSModule *module;
329 JSSMODHeader jssH; 301 JSSMODHeader jssH;
330 Uint8 *buf = bufStart;
331 size_t bufLeft = bufSize;
332 int index; 302 int index;
333 303
334 assert(ppModule != NULL);
335 assert(bufStart != NULL);
336 *ppModule = NULL; 304 *ppModule = NULL;
337 305
338 // Check the JSSMOD header 306 // Check the JSSMOD header
339 memset(&jssH, 0, sizeof(jssH)); 307 memset(&jssH, 0, sizeof(jssH));
340 JSGETBUF(&jssH, JSSMODHeader); 308 JSGETBUF(&jssH, JSSMODHeader);
384 // Parse the patterns 352 // Parse the patterns
385 for (index = 0; index < module->npatterns; index++) 353 for (index = 0; index < module->npatterns; index++)
386 { 354 {
387 JSSMODPattern jssP; 355 JSSMODPattern jssP;
388 int result = DMERR_INVALID_DATA; 356 int result = DMERR_INVALID_DATA;
389 size_t bufSize;
390 357
391 // Get header and check size 358 // Get header and check size
392 memset(&jssP, 0, sizeof(jssP)); 359 memset(&jssP, 0, sizeof(jssP));
393 JSGETBUF(&jssP, JSSMODPattern); 360 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 361
401 // Allocate pattern 362 // Allocate pattern
402 module->patterns[index] = jssAllocatePattern(jssP.nrows, module->nchannels); 363 module->patterns[index] = jssAllocatePattern(jssP.nrows, module->nchannels);
403 if (module->patterns[index] == NULL) 364 if (module->patterns[index] == NULL)
404 { 365 {
409 // Get pattern data 370 // Get pattern data
410 switch (jssH.patMode) 371 switch (jssH.patMode)
411 { 372 {
412 #ifdef JM_SUP_PATMODE_1 373 #ifdef JM_SUP_PATMODE_1
413 case PATMODE_RAW_HORIZ: 374 case PATMODE_RAW_HORIZ:
414 result = jssGetPatternRawHoriz(buf, &bufSize, module->patterns[index]); 375 result = jssGetPatternRawHoriz(inFile, module->patterns[index]);
415 break; 376 break;
416 #endif 377 #endif
417 #ifdef JM_SUP_PATMODE_2 378 #ifdef JM_SUP_PATMODE_2
418 case PATMODE_COMP_HORIZ: 379 case PATMODE_COMP_HORIZ:
419 result = jssGetPatternCompHoriz(buf, &bufSize, module->patterns[index]); 380 result = jssGetPatternCompHoriz(inFile, module->patterns[index]);
420 break; 381 break;
421 #endif 382 #endif
422 #ifdef JM_SUP_PATMODE_3 383 #ifdef JM_SUP_PATMODE_3
423 case PATMODE_RAW_VERT: 384 case PATMODE_RAW_VERT:
424 result = jssGetPatternRawVert(buf, &bufSize, module->patterns[index]); 385 result = jssGetPatternRawVert(inFile, module->patterns[index]);
425 break; 386 break;
426 #endif 387 #endif
427 #ifdef JM_SUP_PATMODE_4 388 #ifdef JM_SUP_PATMODE_4
428 case PATMODE_COMP_VERT: 389 case PATMODE_COMP_VERT:
429 result = jssGetPatternCompVert(buf, &bufSize, module->patterns[index]); 390 result = jssGetPatternCompVert(inFile, module->patterns[index]);
430 break; 391 break;
431 #endif 392 #endif
432 #ifdef JM_SUP_PATMODE_5 393 #ifdef JM_SUP_PATMODE_5
433 case PATMODE_RAW_ELEM: 394 case PATMODE_RAW_ELEM:
434 result = jssGetPatternRawVertElem(buf, &bufSize, module->patterns[index]); 395 result = jssGetPatternRawVertElem(inFile, module->patterns[index]);
435 break; 396 break;
436 #endif 397 #endif
437 default: 398 default:
438 JSSERROR(DMERR_INVALID_DATA, DMERR_INVALID_DATA, 399 JSSERROR(DMERR_INVALID_DATA, DMERR_INVALID_DATA,
439 "Unsupported pattern mode %d. Check compilation options.", jssH.patMode); 400 "Unsupported pattern mode %d. Check compilation options.", jssH.patMode);
440 break; 401 break;
441 } 402 }
442 403
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) 404 if (result != DMERR_OK)
450 { 405 {
451 JSSERROR(result, result, "Error in unpacking pattern #%i data\n", index); 406 JSSERROR(result, result, "Error in unpacking pattern #%i data\n", index);
452 } 407 }
453
454 buf += jssP.size;
455 bufLeft -= jssP.size;
456 } 408 }
457 409
458 #ifdef JM_SUP_EXT_INSTR 410 #ifdef JM_SUP_EXT_INSTR
459 // Read extended instruments 411 // Read extended instruments
460 for (index = 0; index < module->nextInstruments; index++) 412 for (index = 0; index < module->nextInstruments; index++)
536 if (inst->flags & jsf16bit) 488 if (inst->flags & jsf16bit)
537 sz = inst->size * sizeof(Uint16); 489 sz = inst->size * sizeof(Uint16);
538 else 490 else
539 sz = inst->size * sizeof(Uint8); 491 sz = inst->size * sizeof(Uint8);
540 492
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 493 // Allocate
550 if ((inst->data = dmMalloc(sz)) == NULL) 494 if ((inst->data = dmMalloc(sz)) == NULL)
551 { 495 {
552 JSSERROR(DMERR_MALLOC, DMERR_MALLOC, 496 JSSERROR(DMERR_MALLOC, DMERR_MALLOC,
553 "Could not allocate sample data #%d\n", index); 497 "Could not allocate sample data #%d\n", index);
554 } 498 }
555 499
556 // Copy data 500 // Copy data
557 memcpy(inst->data, buf, sz); 501 if (!dmf_read_str(inFile, inst->data, sz))
558 buf += sz; 502 {
559 bufLeft -= sz; 503 JSSERROR(DMERR_FREAD, DMERR_FREAD,
504 "Could not read sample data for #%d\n", index);
505 }
560 506
561 // Convert, if needed 507 // Convert, if needed
562 if (inst->flags & jsf16bit) 508 if (inst->flags & jsf16bit)
563 jssDecodeSample16(inst->data, inst->size, inst->convFlags); 509 jssDecodeSample16(inst->data, inst->size, inst->convFlags);
564 else 510 else