Mercurial > hg > dmlib
annotate tools/xm2jss.c @ 1237:8b6ed580e800
Add sanity check to order list writing.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Fri, 06 Mar 2015 16:37:15 +0200 |
parents | 5b8245e5f785 |
children | 5e2b90e3e4bc |
rev | line source |
---|---|
0 | 1 /* |
2 * xm2jss - Convert XM module to JSSMOD | |
3 * Programmed and designed by Matti 'ccr' Hamalainen | |
4 * (C) Copyright 2006-2009 Tecnic Software productions (TNSP) | |
5 * | |
6 * Please read file 'COPYING' for information on license and distribution. | |
7 */ | |
8 #include <stdio.h> | |
9 #include <errno.h> | |
10 #include "jss.h" | |
11 #include "jssmod.h" | |
184
50f55def91e5
Add a minor optimization in the conversion.
Matti Hamalainen <ccr@tnsp.org>
parents:
86
diff
changeset
|
12 #include "jssplr.h" |
0 | 13 #include "dmlib.h" |
14 #include "dmargs.h" | |
15 #include "dmres.h" | |
285
245b15cd1919
Don't link libSDL uselessly to utilities that do not actually use it.
Matti Hamalainen <ccr@tnsp.org>
parents:
202
diff
changeset
|
16 #include "dmmutex.h" |
245b15cd1919
Don't link libSDL uselessly to utilities that do not actually use it.
Matti Hamalainen <ccr@tnsp.org>
parents:
202
diff
changeset
|
17 |
0 | 18 |
184
50f55def91e5
Add a minor optimization in the conversion.
Matti Hamalainen <ccr@tnsp.org>
parents:
86
diff
changeset
|
19 #define jmpNMODEffectTable (36) |
50f55def91e5
Add a minor optimization in the conversion.
Matti Hamalainen <ccr@tnsp.org>
parents:
86
diff
changeset
|
20 static const char jmpMODEffectTable[jmpNMODEffectTable] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; |
1099 | 21 #define JM_SAMPLE_MODE_MASK (jsampFlipSign | jsampSwapEndianess | jsampSplit | jsampDelta) |
184
50f55def91e5
Add a minor optimization in the conversion.
Matti Hamalainen <ccr@tnsp.org>
parents:
86
diff
changeset
|
22 |
0 | 23 |
300 | 24 char *optInFilename = NULL, *optOutFilename = NULL; |
0 | 25 BOOL optIgnoreErrors = FALSE, |
26 optStripExtInstr = FALSE, | |
27 optStripInstr = FALSE, | |
28 optStripSamples = FALSE, | |
29 optOptimize = FALSE; | |
30 | |
31 int optPatternMode = PATMODE_COMP_HORIZ, | |
32 optSampMode16 = jsampDelta, | |
33 optSampMode8 = jsampFlipSign | jsampDelta; | |
34 | |
35 | |
36 static const char* patModeTable[PATMODE_LAST] = | |
37 { | |
38 "Raw horizontal", | |
39 "Compressed horizontal (similar to XM modules)", | |
40 "Raw vertical", | |
41 "Compressed vertical", | |
42 "Raw vertical for each element", | |
43 }; | |
44 | |
45 | |
860
daebbf28953d
The argument handling API in dmargs* was synced with th-libs.
Matti Hamalainen <ccr@tnsp.org>
parents:
856
diff
changeset
|
46 static const DMOptArg optList[] = |
daebbf28953d
The argument handling API in dmargs* was synced with th-libs.
Matti Hamalainen <ccr@tnsp.org>
parents:
856
diff
changeset
|
47 { |
0 | 48 { 0, '?', "help", "Show this help", OPT_NONE }, |
337 | 49 { 1, 'v', "verbose", "Be more verbose", OPT_NONE }, |
50 { 2, 'i', "ignore", "Ignore errors", OPT_NONE }, | |
51 { 3, 'p', "patterns", "Pattern storage mode", OPT_ARGREQ }, | |
52 { 4, 'E', "strip-ext-instr","Strip ext. instruments (implies -I -S)", OPT_NONE }, | |
53 { 5, 'I', "strip-instr", "Strip instruments (implies -S)", OPT_NONE }, | |
54 { 6, 'S', "strip-samples", "Strip instr. sampledata", OPT_NONE }, | |
0 | 55 { 7, '8', "smode8", "8-bit sample conversion flags", OPT_ARGREQ }, |
56 { 8, '1', "smode16", "16-bit sample conversion flags", OPT_ARGREQ }, | |
337 | 57 { 9, 'O', "optimize", "Optimize module", OPT_NONE }, |
0 | 58 }; |
59 | |
60 const int optListN = sizeof(optList) / sizeof(optList[0]); | |
61 | |
62 | |
63 void argShowHelp() | |
64 { | |
65 int i; | |
66 | |
337 | 67 dmPrintBanner(stdout, dmProgName, "[options] <input.xm> <output.jmod>"); |
860
daebbf28953d
The argument handling API in dmargs* was synced with th-libs.
Matti Hamalainen <ccr@tnsp.org>
parents:
856
diff
changeset
|
68 dmArgsPrintHelp(stdout, optList, optListN, 0); |
0 | 69 |
70 printf("\n" | |
71 "Pattern storage modes:\n"); | |
1235
5b8245e5f785
Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
1233
diff
changeset
|
72 |
0 | 73 for (i = 1; i < PATMODE_LAST; i++) |
74 printf(" %d = %s\n", i, patModeTable[i-1]); | |
1235
5b8245e5f785
Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
1233
diff
changeset
|
75 |
0 | 76 printf( |
77 "\n" | |
78 "Sample data conversion flags (summative):\n" | |
79 " 1 = Delta encoding (DEF 8 & 16)\n" | |
80 " 2 = Flip signedness (DEF 8)\n" | |
81 " 4 = Swap endianess (affects 16-bit only)\n" | |
82 " 8 = Split and de-interleave hi/lo bytes (affects 16-bit only)\n" | |
83 "\n" | |
84 ); | |
85 } | |
86 | |
87 BOOL argHandleOpt(const int optN, char *optArg, char *currArg) | |
88 { | |
89 (void) optArg; | |
1235
5b8245e5f785
Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
1233
diff
changeset
|
90 |
0 | 91 switch (optN) |
92 { | |
93 case 0: | |
94 argShowHelp(); | |
95 exit(0); | |
96 break; | |
97 | |
98 case 1: | |
337 | 99 dmVerbosity++; |
100 break; | |
101 | |
102 case 2: | |
0 | 103 optIgnoreErrors = TRUE; |
104 break; | |
105 | |
337 | 106 case 3: |
0 | 107 optPatternMode = atoi(optArg); |
108 if (optPatternMode <= 0 || optPatternMode >= PATMODE_LAST) | |
109 { | |
958
985225a93aeb
Add error code parameter to dmError() and dmErrorVA().
Matti Hamalainen <ccr@tnsp.org>
parents:
860
diff
changeset
|
110 dmErrorMsg("Unknown pattern conversion mode %d\n", optPatternMode); |
0 | 111 return FALSE; |
112 } | |
113 break; | |
114 | |
337 | 115 case 4: optStripExtInstr = TRUE; break; |
116 case 5: optStripInstr = TRUE; break; | |
117 case 6: optStripSamples = TRUE; break; | |
118 | |
1099 | 119 case 7: optSampMode8 = atoi(optArg) & JM_SAMPLE_MODE_MASK; break; |
120 case 8: optSampMode16 = atoi(optArg) & JM_SAMPLE_MODE_MASK; break; | |
0 | 121 |
337 | 122 case 9: optOptimize = TRUE; break; |
0 | 123 |
124 default: | |
958
985225a93aeb
Add error code parameter to dmError() and dmErrorVA().
Matti Hamalainen <ccr@tnsp.org>
parents:
860
diff
changeset
|
125 dmErrorMsg("Unknown argument '%s'.\n", currArg); |
0 | 126 return FALSE; |
127 } | |
1235
5b8245e5f785
Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
1233
diff
changeset
|
128 |
0 | 129 return TRUE; |
130 } | |
131 | |
132 | |
133 BOOL argHandleFile(char *currArg) | |
134 { | |
135 // Was not option argument | |
300 | 136 if (!optInFilename) |
137 optInFilename = currArg; | |
337 | 138 else |
300 | 139 if (!optOutFilename) |
140 optOutFilename = currArg; | |
0 | 141 else |
142 { | |
958
985225a93aeb
Add error code parameter to dmError() and dmErrorVA().
Matti Hamalainen <ccr@tnsp.org>
parents:
860
diff
changeset
|
143 dmErrorMsg("Too many filename arguments specified, '%s'.\n", currArg); |
0 | 144 return FALSE; |
145 } | |
1235
5b8245e5f785
Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
1233
diff
changeset
|
146 |
0 | 147 return TRUE; |
148 } | |
149 | |
150 | |
151 /* These functions and the macro mess are meant to make the | |
152 * conversion routines themselves clearer and simpler. | |
153 */ | |
154 BOOL jsPutByte(Uint8 *patBuf, size_t patBufSize, size_t *npatBuf, Uint8 val) | |
155 { | |
156 if (*npatBuf >= patBufSize) | |
157 return FALSE; | |
158 else | |
159 { | |
160 patBuf[*npatBuf] = val; | |
161 (*npatBuf)++; | |
162 return TRUE; | |
163 } | |
164 } | |
165 | |
166 #define JSPUTBYTE(x) do { if (!jsPutByte(patBuf, patBufSize, patSize, x)) return DMERR_BOUNDS; } while (0) | |
167 | |
168 #define JSCOMP(x,z) do { if ((x) != jsetNotSet) { qflags |= (z); qcomp++; } } while (0) | |
169 | |
170 #define JSCOMPPUT(xf,xv,qv) do { \ | |
171 if (qflags & (xf)) { \ | |
172 if ((xv) < 0 || (xv) > 255) \ | |
173 JSSERROR(DMERR_BOUNDS, DMERR_BOUNDS, \ | |
174 "%s value out of bounds %d.\n", qv, (xv)); \ | |
175 JSPUTBYTE(xv); \ | |
176 } \ | |
177 } while (0) | |
178 | |
179 #define JSCONVPUT(xv,qv) do { \ | |
180 if ((xv) != jsetNotSet) { \ | |
181 if ((xv) < 0 || (xv) > 254) \ | |
182 JSSERROR(DMERR_BOUNDS, DMERR_BOUNDS, \ | |
183 "%s value out of bounds %d.\n", qv, (xv)); \ | |
184 JSPUTBYTE((xv) + 1); \ | |
185 } else { \ | |
186 JSPUTBYTE(0); \ | |
187 } \ | |
188 } while (0) | |
189 | |
190 | |
191 /* Convert a note | |
192 */ | |
1207
59b5821b5cf9
Rename function arguments.
Matti Hamalainen <ccr@tnsp.org>
parents:
1201
diff
changeset
|
193 static int jssConvertNote( |
59b5821b5cf9
Rename function arguments.
Matti Hamalainen <ccr@tnsp.org>
parents:
1201
diff
changeset
|
194 Uint8 *patBuf, const size_t patBufSize, |
59b5821b5cf9
Rename function arguments.
Matti Hamalainen <ccr@tnsp.org>
parents:
1201
diff
changeset
|
195 size_t *patSize, const JSSNote *pnote) |
0 | 196 { |
197 Uint8 tmp; | |
1207
59b5821b5cf9
Rename function arguments.
Matti Hamalainen <ccr@tnsp.org>
parents:
1201
diff
changeset
|
198 if (pnote->note == jsetNotSet) |
0 | 199 tmp = 0; |
1194 | 200 else |
1207
59b5821b5cf9
Rename function arguments.
Matti Hamalainen <ccr@tnsp.org>
parents:
1201
diff
changeset
|
201 if (pnote->note == jsetNoteOff) |
0 | 202 tmp = 127; |
203 else | |
1207
59b5821b5cf9
Rename function arguments.
Matti Hamalainen <ccr@tnsp.org>
parents:
1201
diff
changeset
|
204 tmp = pnote->note + 1; |
0 | 205 |
206 if (tmp > 0x7f) | |
207 JSSERROR(DMERR_BOUNDS, DMERR_BOUNDS, "Note value out of bounds %d > 0x7f.\n", tmp); | |
208 | |
209 JSPUTBYTE(tmp & 0x7f); | |
1235
5b8245e5f785
Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
1233
diff
changeset
|
210 |
1207
59b5821b5cf9
Rename function arguments.
Matti Hamalainen <ccr@tnsp.org>
parents:
1201
diff
changeset
|
211 JSCONVPUT(pnote->instrument, "Instrument"); |
59b5821b5cf9
Rename function arguments.
Matti Hamalainen <ccr@tnsp.org>
parents:
1201
diff
changeset
|
212 JSCONVPUT(pnote->volume, "Volume"); |
59b5821b5cf9
Rename function arguments.
Matti Hamalainen <ccr@tnsp.org>
parents:
1201
diff
changeset
|
213 JSCONVPUT(pnote->effect, "Effect"); |
1235
5b8245e5f785
Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
1233
diff
changeset
|
214 |
1207
59b5821b5cf9
Rename function arguments.
Matti Hamalainen <ccr@tnsp.org>
parents:
1201
diff
changeset
|
215 tmp = (pnote->param != jsetNotSet) ? pnote->param : 0; |
0 | 216 JSPUTBYTE(tmp); |
1235
5b8245e5f785
Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
1233
diff
changeset
|
217 |
0 | 218 return DMERR_OK; |
219 } | |
220 | |
221 | |
222 /* Compress a note | |
223 */ | |
1207
59b5821b5cf9
Rename function arguments.
Matti Hamalainen <ccr@tnsp.org>
parents:
1201
diff
changeset
|
224 static int jssCompressNote( |
59b5821b5cf9
Rename function arguments.
Matti Hamalainen <ccr@tnsp.org>
parents:
1201
diff
changeset
|
225 Uint8 *patBuf, const size_t patBufSize, |
59b5821b5cf9
Rename function arguments.
Matti Hamalainen <ccr@tnsp.org>
parents:
1201
diff
changeset
|
226 size_t *patSize, const JSSNote *pnote) |
0 | 227 { |
228 Uint8 qflags = 0; | |
229 int qcomp = 0; | |
1201 | 230 |
231 // Determine what would get stored, | |
1235
5b8245e5f785
Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
1233
diff
changeset
|
232 // aka actually how much space we use |
1210
6b48bad13399
Rename pattern note packing flag COMP_* constants to JM_COMP_*.
Matti Hamalainen <ccr@tnsp.org>
parents:
1209
diff
changeset
|
233 JSCOMP(pnote->note, JM_COMP_NOTE); |
6b48bad13399
Rename pattern note packing flag COMP_* constants to JM_COMP_*.
Matti Hamalainen <ccr@tnsp.org>
parents:
1209
diff
changeset
|
234 JSCOMP(pnote->instrument, JM_COMP_INSTRUMENT); |
6b48bad13399
Rename pattern note packing flag COMP_* constants to JM_COMP_*.
Matti Hamalainen <ccr@tnsp.org>
parents:
1209
diff
changeset
|
235 JSCOMP(pnote->volume, JM_COMP_VOLUME); |
6b48bad13399
Rename pattern note packing flag COMP_* constants to JM_COMP_*.
Matti Hamalainen <ccr@tnsp.org>
parents:
1209
diff
changeset
|
236 JSCOMP(pnote->effect, JM_COMP_EFFECT); |
1207
59b5821b5cf9
Rename function arguments.
Matti Hamalainen <ccr@tnsp.org>
parents:
1201
diff
changeset
|
237 if (pnote->param != jsetNotSet && pnote->param != 0) |
0 | 238 { |
1210
6b48bad13399
Rename pattern note packing flag COMP_* constants to JM_COMP_*.
Matti Hamalainen <ccr@tnsp.org>
parents:
1209
diff
changeset
|
239 qflags |= JM_COMP_PARAM; |
0 | 240 qcomp++; |
241 } | |
1235
5b8245e5f785
Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
1233
diff
changeset
|
242 |
0 | 243 if (qcomp < 4) |
244 { | |
1201 | 245 // Okay, it's less than 4 bytes, so use compressed |
0 | 246 JSPUTBYTE(qflags | 0x80); |
1235
5b8245e5f785
Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
1233
diff
changeset
|
247 |
1207
59b5821b5cf9
Rename function arguments.
Matti Hamalainen <ccr@tnsp.org>
parents:
1201
diff
changeset
|
248 if (pnote->note != jsetNotSet) |
0 | 249 { |
1207
59b5821b5cf9
Rename function arguments.
Matti Hamalainen <ccr@tnsp.org>
parents:
1201
diff
changeset
|
250 Uint8 tmp = (pnote->note != jsetNoteOff) ? pnote->note : 127; |
0 | 251 if (tmp > 0x7f) |
252 JSSERROR(DMERR_BOUNDS, DMERR_BOUNDS, "Note value out of bounds %d > 0x7f.\n", tmp); | |
253 JSPUTBYTE(tmp); | |
254 } | |
1235
5b8245e5f785
Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
1233
diff
changeset
|
255 |
1210
6b48bad13399
Rename pattern note packing flag COMP_* constants to JM_COMP_*.
Matti Hamalainen <ccr@tnsp.org>
parents:
1209
diff
changeset
|
256 JSCOMPPUT(JM_COMP_INSTRUMENT, pnote->instrument, "Instrument"); |
6b48bad13399
Rename pattern note packing flag COMP_* constants to JM_COMP_*.
Matti Hamalainen <ccr@tnsp.org>
parents:
1209
diff
changeset
|
257 JSCOMPPUT(JM_COMP_VOLUME, pnote->volume, "Volume"); |
6b48bad13399
Rename pattern note packing flag COMP_* constants to JM_COMP_*.
Matti Hamalainen <ccr@tnsp.org>
parents:
1209
diff
changeset
|
258 JSCOMPPUT(JM_COMP_EFFECT, pnote->effect, "Effect"); |
6b48bad13399
Rename pattern note packing flag COMP_* constants to JM_COMP_*.
Matti Hamalainen <ccr@tnsp.org>
parents:
1209
diff
changeset
|
259 JSCOMPPUT(JM_COMP_PARAM, pnote->param, "Param"); |
1201 | 260 } |
261 else | |
262 { | |
263 // Was 4 bytes or more, just dump it all in .. | |
1207
59b5821b5cf9
Rename function arguments.
Matti Hamalainen <ccr@tnsp.org>
parents:
1201
diff
changeset
|
264 return jssConvertNote(patBuf, patBufSize, patSize, pnote); |
1201 | 265 } |
266 | |
0 | 267 return DMERR_OK; |
268 } | |
269 | |
270 | |
271 /* Compress pattern | |
272 */ | |
1207
59b5821b5cf9
Rename function arguments.
Matti Hamalainen <ccr@tnsp.org>
parents:
1201
diff
changeset
|
273 static int jssConvertPatternCompHoriz( |
59b5821b5cf9
Rename function arguments.
Matti Hamalainen <ccr@tnsp.org>
parents:
1201
diff
changeset
|
274 Uint8 *patBuf, const size_t patBufSize, |
59b5821b5cf9
Rename function arguments.
Matti Hamalainen <ccr@tnsp.org>
parents:
1201
diff
changeset
|
275 size_t *patSize, const JSSPattern *pattern) |
0 | 276 { |
277 int row, channel; | |
278 *patSize = 0; | |
1235
5b8245e5f785
Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
1233
diff
changeset
|
279 |
0 | 280 for (row = 0; row < pattern->nrows; row++) |
281 for (channel = 0; channel < pattern->nchannels; channel++) | |
282 { | |
1207
59b5821b5cf9
Rename function arguments.
Matti Hamalainen <ccr@tnsp.org>
parents:
1201
diff
changeset
|
283 const JSSNote *pnote = &pattern->data[(pattern->nchannels * row) + channel]; |
59b5821b5cf9
Rename function arguments.
Matti Hamalainen <ccr@tnsp.org>
parents:
1201
diff
changeset
|
284 const int res = jssCompressNote(patBuf, patBufSize, patSize, pnote); |
0 | 285 if (res != DMERR_OK) |
286 { | |
287 JSSERROR(res, res, "Note compression failed [patBuf=%p, patBufSize=%d, patSize=%d, row=%d, chn=%d]\n", | |
288 patBuf, patBufSize, *patSize, row, channel); | |
289 return res; | |
290 } | |
291 } | |
1235
5b8245e5f785
Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
1233
diff
changeset
|
292 |
0 | 293 return DMERR_OK; |
294 } | |
295 | |
296 | |
1207
59b5821b5cf9
Rename function arguments.
Matti Hamalainen <ccr@tnsp.org>
parents:
1201
diff
changeset
|
297 static int jssConvertPatternCompVert( |
59b5821b5cf9
Rename function arguments.
Matti Hamalainen <ccr@tnsp.org>
parents:
1201
diff
changeset
|
298 Uint8 *patBuf, const size_t patBufSize, |
59b5821b5cf9
Rename function arguments.
Matti Hamalainen <ccr@tnsp.org>
parents:
1201
diff
changeset
|
299 size_t *patSize, const JSSPattern *pattern) |
0 | 300 { |
301 int row, channel; | |
302 *patSize = 0; | |
1235
5b8245e5f785
Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
1233
diff
changeset
|
303 |
0 | 304 for (channel = 0; channel < pattern->nchannels; channel++) |
305 for (row = 0; row < pattern->nrows; row++) | |
306 { | |
1207
59b5821b5cf9
Rename function arguments.
Matti Hamalainen <ccr@tnsp.org>
parents:
1201
diff
changeset
|
307 const JSSNote *pnote = &pattern->data[(pattern->nchannels * row) + channel]; |
59b5821b5cf9
Rename function arguments.
Matti Hamalainen <ccr@tnsp.org>
parents:
1201
diff
changeset
|
308 const int res = jssCompressNote(patBuf, patBufSize, patSize, pnote); |
0 | 309 if (res != DMERR_OK) |
310 { | |
311 JSSERROR(res, res, "Note compression failed [patBuf=%p, patBufSize=%d, patSize=%d, row=%d, chn=%d]\n", | |
312 patBuf, patBufSize, *patSize, row, channel); | |
313 return res; | |
314 } | |
315 } | |
1235
5b8245e5f785
Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
1233
diff
changeset
|
316 |
0 | 317 return DMERR_OK; |
318 } | |
319 | |
320 | |
321 /* Convert a pattern | |
322 */ | |
1207
59b5821b5cf9
Rename function arguments.
Matti Hamalainen <ccr@tnsp.org>
parents:
1201
diff
changeset
|
323 static int jssConvertPatternRawHoriz( |
59b5821b5cf9
Rename function arguments.
Matti Hamalainen <ccr@tnsp.org>
parents:
1201
diff
changeset
|
324 Uint8 *patBuf, const size_t patBufSize, |
59b5821b5cf9
Rename function arguments.
Matti Hamalainen <ccr@tnsp.org>
parents:
1201
diff
changeset
|
325 size_t *patSize, const JSSPattern *pattern) |
0 | 326 { |
327 int row, channel; | |
328 *patSize = 0; | |
1235
5b8245e5f785
Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
1233
diff
changeset
|
329 |
0 | 330 for (row = 0; row < pattern->nrows; row++) |
331 for (channel = 0; channel < pattern->nchannels; channel++) | |
332 { | |
1207
59b5821b5cf9
Rename function arguments.
Matti Hamalainen <ccr@tnsp.org>
parents:
1201
diff
changeset
|
333 const JSSNote *pnote = &pattern->data[(pattern->nchannels * row) + channel]; |
59b5821b5cf9
Rename function arguments.
Matti Hamalainen <ccr@tnsp.org>
parents:
1201
diff
changeset
|
334 const int res = jssConvertNote(patBuf, patBufSize, patSize, pnote); |
0 | 335 if (res != DMERR_OK) |
336 { | |
337 JSSERROR(res, res, "Note conversion failed [patBuf=%p, patBufSize=%d, patSize=%d, row=%d, chn=%d]\n", | |
338 patBuf, patBufSize, *patSize, row, channel); | |
339 return res; | |
340 } | |
341 } | |
1235
5b8245e5f785
Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
1233
diff
changeset
|
342 |
0 | 343 return DMERR_OK; |
344 } | |
345 | |
346 | |
1207
59b5821b5cf9
Rename function arguments.
Matti Hamalainen <ccr@tnsp.org>
parents:
1201
diff
changeset
|
347 static int jssConvertPatternRawVert( |
59b5821b5cf9
Rename function arguments.
Matti Hamalainen <ccr@tnsp.org>
parents:
1201
diff
changeset
|
348 Uint8 *patBuf, const size_t patBufSize, |
59b5821b5cf9
Rename function arguments.
Matti Hamalainen <ccr@tnsp.org>
parents:
1201
diff
changeset
|
349 size_t *patSize, const JSSPattern *pattern) |
0 | 350 { |
351 int row, channel; | |
352 *patSize = 0; | |
1235
5b8245e5f785
Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
1233
diff
changeset
|
353 |
0 | 354 for (channel = 0; channel < pattern->nchannels; channel++) |
355 for (row = 0; row < pattern->nrows; row++) | |
356 { | |
1207
59b5821b5cf9
Rename function arguments.
Matti Hamalainen <ccr@tnsp.org>
parents:
1201
diff
changeset
|
357 const JSSNote *pnote = &pattern->data[(pattern->nchannels * row) + channel]; |
59b5821b5cf9
Rename function arguments.
Matti Hamalainen <ccr@tnsp.org>
parents:
1201
diff
changeset
|
358 const int res = jssConvertNote(patBuf, patBufSize, patSize, pnote); |
0 | 359 if (res != DMERR_OK) |
360 { | |
361 JSSERROR(res, res, "Note conversion failed [patBuf=%p, patBufSize=%d, patSize=%d, row=%d, chn=%d]\n", | |
362 patBuf, patBufSize, *patSize, row, channel); | |
363 return res; | |
364 } | |
365 } | |
1235
5b8245e5f785
Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
1233
diff
changeset
|
366 |
0 | 367 return DMERR_OK; |
368 } | |
369 | |
370 | |
371 #define JSFOREACHNOTE1 \ | |
372 for (channel = 0; channel < pattern->nchannels; channel++) \ | |
373 for (row = 0; row < pattern->nrows; row++) { \ | |
1207
59b5821b5cf9
Rename function arguments.
Matti Hamalainen <ccr@tnsp.org>
parents:
1201
diff
changeset
|
374 const JSSNote *pnote = &pattern->data[(pattern->nchannels * row) + channel]; |
0 | 375 |
376 #define JSFOREACHNOTE2 } | |
377 | |
1207
59b5821b5cf9
Rename function arguments.
Matti Hamalainen <ccr@tnsp.org>
parents:
1201
diff
changeset
|
378 static int jssConvertPatternRawElem( |
59b5821b5cf9
Rename function arguments.
Matti Hamalainen <ccr@tnsp.org>
parents:
1201
diff
changeset
|
379 Uint8 *patBuf, const size_t patBufSize, |
59b5821b5cf9
Rename function arguments.
Matti Hamalainen <ccr@tnsp.org>
parents:
1201
diff
changeset
|
380 size_t *patSize, const JSSPattern *pattern) |
0 | 381 { |
382 Uint8 tmp; | |
383 int row, channel; | |
384 *patSize = 0; | |
1235
5b8245e5f785
Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
1233
diff
changeset
|
385 |
0 | 386 JSFOREACHNOTE1; |
1207
59b5821b5cf9
Rename function arguments.
Matti Hamalainen <ccr@tnsp.org>
parents:
1201
diff
changeset
|
387 if (pnote->note == jsetNotSet) |
0 | 388 tmp = 0; |
1194 | 389 else |
1207
59b5821b5cf9
Rename function arguments.
Matti Hamalainen <ccr@tnsp.org>
parents:
1201
diff
changeset
|
390 if (pnote->note == jsetNoteOff) |
0 | 391 tmp = 127; |
392 else | |
1207
59b5821b5cf9
Rename function arguments.
Matti Hamalainen <ccr@tnsp.org>
parents:
1201
diff
changeset
|
393 tmp = pnote->note + 1; |
1194 | 394 |
0 | 395 if (tmp > 0x7f) |
396 JSSERROR(DMERR_BOUNDS, DMERR_BOUNDS, "Note value out of bounds %d > 0x7f.\n", tmp); | |
1194 | 397 |
0 | 398 JSPUTBYTE(tmp); |
399 JSFOREACHNOTE2; | |
1235
5b8245e5f785
Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
1233
diff
changeset
|
400 |
0 | 401 JSFOREACHNOTE1; |
1207
59b5821b5cf9
Rename function arguments.
Matti Hamalainen <ccr@tnsp.org>
parents:
1201
diff
changeset
|
402 JSCONVPUT(pnote->instrument, "Instrument"); |
0 | 403 JSFOREACHNOTE2; |
1235
5b8245e5f785
Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
1233
diff
changeset
|
404 |
0 | 405 JSFOREACHNOTE1; |
1207
59b5821b5cf9
Rename function arguments.
Matti Hamalainen <ccr@tnsp.org>
parents:
1201
diff
changeset
|
406 JSCONVPUT(pnote->volume, "Volume"); |
0 | 407 JSFOREACHNOTE2; |
1235
5b8245e5f785
Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
1233
diff
changeset
|
408 |
0 | 409 JSFOREACHNOTE1; |
1207
59b5821b5cf9
Rename function arguments.
Matti Hamalainen <ccr@tnsp.org>
parents:
1201
diff
changeset
|
410 JSCONVPUT(pnote->effect, "Effect"); |
0 | 411 JSFOREACHNOTE2; |
1235
5b8245e5f785
Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
1233
diff
changeset
|
412 |
0 | 413 JSFOREACHNOTE1; |
1207
59b5821b5cf9
Rename function arguments.
Matti Hamalainen <ccr@tnsp.org>
parents:
1201
diff
changeset
|
414 tmp = (pnote->param != jsetNotSet) ? pnote->param : 0; |
338
cd57ba1130eb
Fixes and improvements in the JMOD saving and loading.
Matti Hamalainen <ccr@tnsp.org>
parents:
337
diff
changeset
|
415 JSPUTBYTE(tmp); |
0 | 416 JSFOREACHNOTE2; |
1235
5b8245e5f785
Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
1233
diff
changeset
|
417 |
0 | 418 return DMERR_OK; |
419 } | |
420 | |
421 #undef JSFOREACHNOTE1 | |
422 #undef JSFOREACHNOTE2 | |
423 | |
424 | |
425 static void jssCopyEnvelope(JSSMODEnvelope *je, JSSEnvelope *e) | |
426 { | |
427 int i; | |
1235
5b8245e5f785
Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
1233
diff
changeset
|
428 |
0 | 429 je->flags = e->flags; |
430 je->npoints = e->npoints; | |
431 je->sustain = e->sustain; | |
432 je->loopS = e->loopS; | |
433 je->loopE = e->loopE; | |
1235
5b8245e5f785
Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
1233
diff
changeset
|
434 |
0 | 435 for (i = 0; i < e->npoints; i++) |
436 { | |
437 je->points[i].frame = e->points[i].frame; | |
438 je->points[i].value = e->points[i].value; | |
439 } | |
440 } | |
441 | |
442 | |
443 /* Save a JSSMOD file | |
444 */ | |
445 int jssSaveJSSMOD(FILE *outFile, JSSModule *m, int patMode, int flags8, int flags16) | |
446 { | |
447 JSSMODHeader jssH; | |
9
c42ee907de9c
Various improvements in xm2jss output.
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
448 int i, pattern, order, instr, totalSize; |
0 | 449 const size_t patBufSize = 64*1024; // 64kB pattern buffer |
450 Uint8 *patBuf; | |
451 | |
452 // Check the module | |
453 if (m == NULL) | |
454 JSSERROR(DMERR_NULLPTR, DMERR_NULLPTR, "Module pointer was NULL\n"); | |
455 | |
1233 | 456 if (m->nchannels < 1 || m->npatterns < 1 || m->norders < 1 || |
457 m->nchannels > jsetMaxChannels || | |
458 m->npatterns > jsetMaxPatterns || | |
459 m->norders > jsetMaxOrders) | |
0 | 460 JSSERROR(DMERR_BOUNDS, DMERR_BOUNDS, |
1195
4d27c4ec8d4d
Use %d instead of %i in formats.
Matti Hamalainen <ccr@tnsp.org>
parents:
1194
diff
changeset
|
461 "Module had invalid values (nchannels=%d, npatterns=%d, norders=%d)\n", |
0 | 462 m->nchannels, m->npatterns, m->norders); |
463 | |
464 // Create the JSSMOD header | |
465 jssH.idMagic[0] = 'J'; | |
466 jssH.idMagic[1] = 'M'; | |
467 jssH.idVersion = JSSMOD_VERSION; | |
1231 | 468 jssH.defFlags = m->defFlags; |
469 jssH.intVersion = m->intVersion; | |
0 | 470 jssH.norders = m->norders; |
471 jssH.npatterns = m->npatterns; | |
472 jssH.nextInstruments = m->nextInstruments; | |
473 jssH.ninstruments = m->ninstruments; | |
474 jssH.defRestartPos = m->defRestartPos; | |
1231 | 475 |
476 jssH.nchannels = m->nchannels; | |
0 | 477 jssH.defSpeed = m->defSpeed; |
478 jssH.defTempo = m->defTempo; | |
479 jssH.patMode = patMode; | |
1209 | 480 |
0 | 481 // Write header |
9
c42ee907de9c
Various improvements in xm2jss output.
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
482 totalSize = sizeof(jssH); |
0 | 483 if (fwrite(&jssH, sizeof(jssH), 1, outFile) != 1) |
484 JSSERROR(DMERR_FWRITE, DMERR_FWRITE, "Could not write JSSMOD header!\n"); | |
485 | |
9
c42ee907de9c
Various improvements in xm2jss output.
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
486 dmMsg(1," * JSSMOD-header 0x%04x, %d bytes.\n", JSSMOD_VERSION, totalSize); |
c42ee907de9c
Various improvements in xm2jss output.
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
487 |
0 | 488 // Write orders list |
9
c42ee907de9c
Various improvements in xm2jss output.
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
489 for (totalSize = order = 0; order < m->norders; order++) |
0 | 490 { |
1237
8b6ed580e800
Add sanity check to order list writing.
Matti Hamalainen <ccr@tnsp.org>
parents:
1235
diff
changeset
|
491 int tmp = m->orderList[order]; |
8b6ed580e800
Add sanity check to order list writing.
Matti Hamalainen <ccr@tnsp.org>
parents:
1235
diff
changeset
|
492 if (tmp == jsetNotSet || tmp > m->npatterns) |
8b6ed580e800
Add sanity check to order list writing.
Matti Hamalainen <ccr@tnsp.org>
parents:
1235
diff
changeset
|
493 JSSERROR(DMERR_INVALID_DATA, DMERR_INVALID_DATA, |
8b6ed580e800
Add sanity check to order list writing.
Matti Hamalainen <ccr@tnsp.org>
parents:
1235
diff
changeset
|
494 "Orderlist entry #%d has invalid value %d.\n", |
8b6ed580e800
Add sanity check to order list writing.
Matti Hamalainen <ccr@tnsp.org>
parents:
1235
diff
changeset
|
495 order, tmp); |
8b6ed580e800
Add sanity check to order list writing.
Matti Hamalainen <ccr@tnsp.org>
parents:
1235
diff
changeset
|
496 |
8b6ed580e800
Add sanity check to order list writing.
Matti Hamalainen <ccr@tnsp.org>
parents:
1235
diff
changeset
|
497 if (!dm_fwrite_le16(outFile, tmp)) |
8b6ed580e800
Add sanity check to order list writing.
Matti Hamalainen <ccr@tnsp.org>
parents:
1235
diff
changeset
|
498 JSSERROR(DMERR_FWRITE, DMERR_FWRITE, |
8b6ed580e800
Add sanity check to order list writing.
Matti Hamalainen <ccr@tnsp.org>
parents:
1235
diff
changeset
|
499 "Could not write JSSMOD orders list entry #%d (%d).\n", |
8b6ed580e800
Add sanity check to order list writing.
Matti Hamalainen <ccr@tnsp.org>
parents:
1235
diff
changeset
|
500 order, tmp); |
8b6ed580e800
Add sanity check to order list writing.
Matti Hamalainen <ccr@tnsp.org>
parents:
1235
diff
changeset
|
501 |
8b6ed580e800
Add sanity check to order list writing.
Matti Hamalainen <ccr@tnsp.org>
parents:
1235
diff
changeset
|
502 totalSize += sizeof(Uint16); |
0 | 503 } |
504 | |
9
c42ee907de9c
Various improvements in xm2jss output.
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
505 dmMsg(1," * %d item orders list, %d bytes.\n", |
c42ee907de9c
Various improvements in xm2jss output.
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
506 m->norders, totalSize); |
c42ee907de9c
Various improvements in xm2jss output.
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
507 |
0 | 508 // Allocate pattern compression buffer |
509 if ((patBuf = dmMalloc(patBufSize)) == NULL) | |
510 JSSERROR(DMERR_MALLOC, DMERR_MALLOC, | |
511 "Error allocating memory for pattern compression buffer.\n"); | |
9
c42ee907de9c
Various improvements in xm2jss output.
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
512 |
1232 | 513 // Convert and write patterns |
9
c42ee907de9c
Various improvements in xm2jss output.
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
514 for (totalSize = pattern = 0; pattern < m->npatterns; pattern++) |
0 | 515 { |
1232 | 516 JSSPattern *pat = m->patterns[pattern]; |
0 | 517 JSSMODPattern patHead; |
518 size_t finalSize = 0; | |
1235
5b8245e5f785
Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
1233
diff
changeset
|
519 |
1232 | 520 if (pat == NULL) |
521 JSSERROR(DMERR_NULLPTR, DMERR_NULLPTR, | |
522 "Pattern #%d was NULL.\n", pattern); | |
1235
5b8245e5f785
Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
1233
diff
changeset
|
523 |
1232 | 524 if (pat->nrows > jsetMaxRows) |
525 JSSERROR(DMERR_INVALID_DATA, DMERR_INVALID_DATA, | |
526 "Pattern #%d has %d rows > %d max.\n", | |
527 pattern, pat->nrows, jsetMaxRows); | |
1235
5b8245e5f785
Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
1233
diff
changeset
|
528 |
0 | 529 switch (patMode) |
530 { | |
531 case PATMODE_RAW_HORIZ: | |
1232 | 532 i = jssConvertPatternRawHoriz(patBuf, patBufSize, &finalSize, pat); |
0 | 533 break; |
534 case PATMODE_COMP_HORIZ: | |
1232 | 535 i = jssConvertPatternCompHoriz(patBuf, patBufSize, &finalSize, pat); |
0 | 536 break; |
537 case PATMODE_RAW_VERT: | |
1232 | 538 i = jssConvertPatternRawVert(patBuf, patBufSize, &finalSize, pat); |
0 | 539 break; |
540 case PATMODE_COMP_VERT: | |
1232 | 541 i = jssConvertPatternCompVert(patBuf, patBufSize, &finalSize, pat); |
0 | 542 break; |
543 case PATMODE_RAW_ELEM: | |
1232 | 544 i = jssConvertPatternRawElem(patBuf, patBufSize, &finalSize, pat); |
0 | 545 break; |
546 default: | |
547 dmFree(patBuf); | |
548 JSSERROR(DMERR_INVALID_DATA, DMERR_INVALID_DATA, | |
549 "Unsupported pattern conversion mode %d.\n", patMode); | |
550 } | |
551 | |
552 if (i != DMERR_OK) | |
553 { | |
554 dmFree(patBuf); | |
1195
4d27c4ec8d4d
Use %d instead of %i in formats.
Matti Hamalainen <ccr@tnsp.org>
parents:
1194
diff
changeset
|
555 JSSERROR(i, i, "Error converting pattern data #%d\n", pattern); |
0 | 556 } |
1211 | 557 |
558 dmMsg(3, " - Pattern %d size %d bytes\n", pattern, finalSize); | |
1232 | 559 patHead.nrows = pat->nrows; |
1211 | 560 patHead.size = finalSize; |
561 totalSize += finalSize + sizeof(patHead); | |
0 | 562 |
1211 | 563 if (fwrite(&patHead, sizeof(patHead), 1, outFile) != 1) |
564 { | |
565 dmFree(patBuf); | |
566 JSSERROR(DMERR_FWRITE, DMERR_FWRITE, | |
567 "Error writing pattern #%d header\n", pattern); | |
568 } | |
0 | 569 |
1211 | 570 if (fwrite(patBuf, sizeof(Uint8), finalSize, outFile) != finalSize) |
571 { | |
572 dmFree(patBuf); | |
573 JSSERROR(DMERR_FWRITE, DMERR_FWRITE, | |
574 "Error writing pattern #%d data\n", pattern); | |
0 | 575 } |
576 } | |
577 dmFree(patBuf); | |
9
c42ee907de9c
Various improvements in xm2jss output.
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
578 dmMsg(1," * %d patterns, %d bytes.\n", m->npatterns, totalSize); |
0 | 579 |
580 // Write extended instruments | |
9
c42ee907de9c
Various improvements in xm2jss output.
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
581 for (totalSize = instr = 0; instr < m->nextInstruments; instr++) |
0 | 582 { |
583 JSSMODExtInstrument jssE; | |
584 JSSExtInstrument *einst = m->extInstruments[instr]; | |
1235
5b8245e5f785
Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
1233
diff
changeset
|
585 |
1167 | 586 dmMemset(&jssE, 0, sizeof(jssE)); |
0 | 587 |
588 if (einst) | |
589 { | |
590 // Create header | |
591 jssE.nsamples = einst->nsamples; | |
592 for (i = 0; i < jsetNNotes; i++) | |
593 { | |
594 int snum = einst->sNumForNotes[i]; | |
1118
de25e0f2b856
Fix sNumForNotes conversion/handling in JSSMOD loader and xm2jss.
Matti Hamalainen <ccr@tnsp.org>
parents:
1116
diff
changeset
|
595 jssE.sNumForNotes[i] = (snum != jsetNotSet) ? snum + 1: 0; |
0 | 596 } |
1235
5b8245e5f785
Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
1233
diff
changeset
|
597 |
0 | 598 jssCopyEnvelope(&jssE.volumeEnv, &(einst->volumeEnv)); |
599 jssCopyEnvelope(&jssE.panningEnv, &(einst->panningEnv)); | |
600 jssE.vibratoType = einst->vibratoType; | |
601 jssE.vibratoSweep = einst->vibratoSweep; | |
602 jssE.vibratoDepth = einst->vibratoDepth; | |
603 jssE.fadeOut = einst->fadeOut; | |
604 } else | |
1195
4d27c4ec8d4d
Use %d instead of %i in formats.
Matti Hamalainen <ccr@tnsp.org>
parents:
1194
diff
changeset
|
605 JSSWARNING(DMERR_NULLPTR, DMERR_NULLPTR, "Extended instrument #%d NULL!\n", instr); |
1235
5b8245e5f785
Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
1233
diff
changeset
|
606 |
0 | 607 // Write to file |
9
c42ee907de9c
Various improvements in xm2jss output.
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
608 totalSize += sizeof(jssE); |
0 | 609 if (fwrite(&jssE, sizeof(jssE), 1, outFile) != 1) |
610 JSSERROR(DMERR_FWRITE, DMERR_FWRITE, | |
1195
4d27c4ec8d4d
Use %d instead of %i in formats.
Matti Hamalainen <ccr@tnsp.org>
parents:
1194
diff
changeset
|
611 "Could not write JSSMOD extended instrument #%d to file!\n", instr); |
0 | 612 } |
9
c42ee907de9c
Various improvements in xm2jss output.
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
613 dmMsg(1," * %d Extended Instruments, %d bytes.\n", m->nextInstruments, totalSize); |
0 | 614 |
615 | |
616 // Write sample instrument headers | |
9
c42ee907de9c
Various improvements in xm2jss output.
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
617 for (totalSize = instr = 0; instr < m->ninstruments; instr++) |
0 | 618 { |
619 JSSMODInstrument jssI; | |
1115 | 620 JSSInstrument *inst = m->instruments[instr]; |
0 | 621 |
1167 | 622 dmMemset(&jssI, 0, sizeof(jssI)); |
0 | 623 |
624 // Create header | |
1115 | 625 if (inst != NULL) |
0 | 626 { |
1115 | 627 jssI.size = inst->size; |
628 jssI.loopS = inst->loopS; | |
629 jssI.loopE = inst->loopE; | |
630 jssI.volume = inst->volume; | |
631 jssI.flags = inst->flags; | |
632 jssI.C4BaseSpeed = inst->C4BaseSpeed; | |
633 jssI.ERelNote = inst->ERelNote; | |
634 jssI.EFineTune = inst->EFineTune; | |
635 jssI.EPanning = inst->EPanning; | |
636 jssI.hasData = (inst->data != NULL) ? TRUE : FALSE; | |
637 jssI.convFlags = (inst->flags & jsf16bit) ? flags16 : flags8; | |
0 | 638 } |
1235
5b8245e5f785
Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
1233
diff
changeset
|
639 else |
1195
4d27c4ec8d4d
Use %d instead of %i in formats.
Matti Hamalainen <ccr@tnsp.org>
parents:
1194
diff
changeset
|
640 JSSWARNING(DMERR_NULLPTR, DMERR_NULLPTR, "Instrument #%d NULL!\n", instr); |
1235
5b8245e5f785
Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
1233
diff
changeset
|
641 |
0 | 642 // Write to file |
9
c42ee907de9c
Various improvements in xm2jss output.
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
643 totalSize += sizeof(jssI); |
0 | 644 if (fwrite(&jssI, sizeof(jssI), 1, outFile) != 1) |
645 JSSERROR(DMERR_FWRITE, DMERR_FWRITE, | |
1195
4d27c4ec8d4d
Use %d instead of %i in formats.
Matti Hamalainen <ccr@tnsp.org>
parents:
1194
diff
changeset
|
646 "Could not write JSSMOD instrument #%d to file!\n", instr); |
0 | 647 } |
9
c42ee907de9c
Various improvements in xm2jss output.
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
648 dmMsg(1," * %d Instrument headers, %d bytes.\n", m->ninstruments, totalSize); |
1235
5b8245e5f785
Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
1233
diff
changeset
|
649 |
0 | 650 // Write sample data |
9
c42ee907de9c
Various improvements in xm2jss output.
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
651 for (totalSize = instr = 0; instr < m->ninstruments; instr++) |
0 | 652 if (m->instruments[instr]) |
653 { | |
654 JSSInstrument *inst = m->instruments[instr]; | |
655 if (inst->data != NULL) | |
656 { | |
657 size_t res; | |
658 if (inst->flags & jsf16bit) | |
659 { | |
660 jssEncodeSample16(inst->data, inst->size, flags16); | |
661 res = fwrite(inst->data, sizeof(Uint16), inst->size, outFile); | |
662 } | |
663 else | |
664 { | |
665 jssEncodeSample8(inst->data, inst->size, flags8); | |
666 res = fwrite(inst->data, sizeof(Uint8), inst->size, outFile); | |
667 } | |
1235
5b8245e5f785
Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
1233
diff
changeset
|
668 |
9
c42ee907de9c
Various improvements in xm2jss output.
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
669 totalSize += inst->size; |
86 | 670 if (res != (size_t) inst->size) |
0 | 671 JSSERROR(DMERR_FWRITE, DMERR_FWRITE, |
1195
4d27c4ec8d4d
Use %d instead of %i in formats.
Matti Hamalainen <ccr@tnsp.org>
parents:
1194
diff
changeset
|
672 "Could not write JSSMOD sample #%d to file!\n", instr); |
0 | 673 } |
674 } | |
9
c42ee907de9c
Various improvements in xm2jss output.
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
675 dmMsg(1," * %d samples, %d bytes.\n", m->ninstruments, totalSize); |
1235
5b8245e5f785
Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
1233
diff
changeset
|
676 |
0 | 677 return DMERR_OK; |
678 } | |
679 | |
680 | |
681 /* Optimize a given module | |
682 */ | |
683 JSSModule *optimizeModule(JSSModule *m) | |
684 { | |
685 BOOL usedPatterns[jsetMaxPatterns + 1], | |
686 usedInstruments[jsetMaxInstruments + 1], | |
687 usedExtInstruments[jsetMaxInstruments + 1]; | |
688 int mapExtInstruments[jsetMaxInstruments + 1], | |
689 mapInstruments[jsetMaxInstruments + 1], | |
690 mapPatterns[jsetMaxPatterns + 1]; | |
691 JSSModule *r = NULL; | |
1097
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
692 int i, n8, n16, unused; |
0 | 693 |
694 // Allocate a new module | |
695 if ((r = jssAllocateModule()) == NULL) | |
696 return NULL; | |
697 | |
698 // Copy things | |
699 r->moduleType = m->moduleType; | |
700 r->moduleName = dm_strdup(m->moduleName); | |
701 r->trackerName = dm_strdup(m->trackerName); | |
702 r->defSpeed = m->defSpeed; | |
703 r->defTempo = m->defTempo; | |
704 r->defFlags = m->defFlags; | |
705 r->defRestartPos = m->defRestartPos; | |
706 r->intVersion = m->intVersion; | |
707 r->nchannels = m->nchannels; | |
708 r->norders = m->norders; | |
709 for (i = 0; i < jsetNChannels; i++) | |
710 r->defPanning[i] = m->defPanning[i]; | |
1235
5b8245e5f785
Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
1233
diff
changeset
|
711 |
0 | 712 // Initialize values |
713 for (i = 0; i <= jsetMaxInstruments; i++) | |
714 { | |
715 usedExtInstruments[i] = FALSE; | |
798 | 716 usedInstruments[i] = FALSE; |
717 mapExtInstruments[i] = jsetNotSet; | |
718 mapInstruments[i] = jsetNotSet; | |
0 | 719 } |
1235
5b8245e5f785
Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
1233
diff
changeset
|
720 |
0 | 721 for (i = 0; i <= jsetMaxPatterns; i++) |
722 { | |
723 usedPatterns[i] = FALSE; | |
798 | 724 mapPatterns[i] = jsetNotSet; |
0 | 725 } |
726 | |
1094 | 727 // |
798 | 728 // Find out all actually used patterns and ext.instruments |
1100 | 729 // by going through all patterns specified in the order list |
1094 | 730 // |
0 | 731 for (i = 0; i < m->norders; i++) |
732 { | |
733 int pattern = m->orderList[i]; | |
734 if (pattern >= 0 && pattern < m->npatterns) | |
735 { | |
736 JSSPattern *p = m->patterns[pattern]; | |
737 if (p != NULL) | |
738 { | |
739 int row, channel; | |
740 JSSNote *n = p->data; | |
1235
5b8245e5f785
Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
1233
diff
changeset
|
741 |
1100 | 742 // Mark this pattern as used |
0 | 743 usedPatterns[pattern] = TRUE; |
1235
5b8245e5f785
Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
1233
diff
changeset
|
744 |
1100 | 745 // Check all notes in this pattern to see what instruments are used |
0 | 746 for (row = 0; row < p->nrows; row++) |
747 for (channel = 0; channel < p->nchannels; channel++, n++) | |
1097
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
748 if (n->instrument != jsetNotSet) |
0 | 749 { |
1097
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
750 if (n->instrument >= 0 && n->instrument < m->nextInstruments) |
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
751 usedExtInstruments[n->instrument] = TRUE; |
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
752 else |
0 | 753 { |
1097
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
754 dmMsg(2, "Pattern 0x%x, row=0x%x, chn=%d has invalid instrument 0x%x\n", |
1111
f9a96fc2a932
Adjust messages to show user-visible (1 based) instrument numbers.
Matti Hamalainen <ccr@tnsp.org>
parents:
1109
diff
changeset
|
755 pattern, row, channel, n->instrument + 1); |
0 | 756 } |
757 } | |
758 } | |
759 else | |
760 { | |
958
985225a93aeb
Add error code parameter to dmError() and dmErrorVA().
Matti Hamalainen <ccr@tnsp.org>
parents:
860
diff
changeset
|
761 dmErrorMsg("Pattern 0x%x is used on order 0x%x, but has no data!\n", |
1094 | 762 pattern, i); |
807
d83dc7e47076
Fix some order list and pattern handling things.
Matti Hamalainen <ccr@tnsp.org>
parents:
798
diff
changeset
|
763 |
d83dc7e47076
Fix some order list and pattern handling things.
Matti Hamalainen <ccr@tnsp.org>
parents:
798
diff
changeset
|
764 // Fix it. |
d83dc7e47076
Fix some order list and pattern handling things.
Matti Hamalainen <ccr@tnsp.org>
parents:
798
diff
changeset
|
765 m->orderList[i] = jsetMaxPatterns; |
0 | 766 } |
767 } | |
768 else | |
769 if (pattern != jsetMaxPatterns) | |
770 { | |
1101 | 771 dmErrorMsg("Order 0x%x has invalid pattern number 0x%x, changing to empty!\n", |
1094 | 772 i, pattern); |
1235
5b8245e5f785
Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
1233
diff
changeset
|
773 |
807
d83dc7e47076
Fix some order list and pattern handling things.
Matti Hamalainen <ccr@tnsp.org>
parents:
798
diff
changeset
|
774 // Fix it. |
d83dc7e47076
Fix some order list and pattern handling things.
Matti Hamalainen <ccr@tnsp.org>
parents:
798
diff
changeset
|
775 m->orderList[i] = jsetMaxPatterns; |
0 | 776 } |
777 } | |
1235
5b8245e5f785
Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
1233
diff
changeset
|
778 |
1094 | 779 // |
1100 | 780 // Find used sample instruments |
1094 | 781 // |
1101 | 782 dmMsg(1, "Checking ext.instruments for used sample instruments...\n"); |
856
415cc781e127
Fix some brain farts in instrument remapping.
Matti Hamalainen <ccr@tnsp.org>
parents:
807
diff
changeset
|
783 for (i = 0; i < jsetMaxInstruments; i++) |
0 | 784 if (usedExtInstruments[i] && m->extInstruments[i] != NULL) |
785 { | |
786 int note; | |
787 JSSExtInstrument *e = m->extInstruments[i]; | |
1094 | 788 |
0 | 789 for (note = 0; note < jsetNNotes; note++) |
790 if (e->sNumForNotes[note] != jsetNotSet) | |
791 { | |
792 int q = e->sNumForNotes[note]; | |
793 if (q >= 0 && q < m->ninstruments) | |
794 { | |
795 usedInstruments[q] = TRUE; | |
796 } | |
797 else | |
798 { | |
958
985225a93aeb
Add error code parameter to dmError() and dmErrorVA().
Matti Hamalainen <ccr@tnsp.org>
parents:
860
diff
changeset
|
799 dmErrorMsg("Ext.instrument #%d sNumForNotes[%d] value out range (%d < %d).\n", |
1111
f9a96fc2a932
Adjust messages to show user-visible (1 based) instrument numbers.
Matti Hamalainen <ccr@tnsp.org>
parents:
1109
diff
changeset
|
800 i + 1, m->ninstruments, q + 1); |
0 | 801 } |
802 } | |
803 } | |
1094 | 804 |
805 // | |
0 | 806 // Create pattern mappings |
1094 | 807 // |
1097
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
808 dmMsg(1, "Creating pattern remaps...\n"); |
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
809 for (unused = i = 0; i <= jsetMaxPatterns; i++) |
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
810 if (usedPatterns[i]) |
0 | 811 { |
1097
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
812 JSSPattern *pat; |
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
813 |
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
814 if (i >= m->npatterns) |
0 | 815 { |
1097
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
816 dmErrorMsg("Pattern 0x%x >= 0x%x, but used!\n", i, m->npatterns); |
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
817 continue; |
0 | 818 } |
1097
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
819 |
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
820 if ((pat = m->patterns[i]) == NULL) |
0 | 821 { |
1097
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
822 dmErrorMsg("Pattern 0x%x used but is NULL.\n", i); |
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
823 continue; |
0 | 824 } |
1235
5b8245e5f785
Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
1233
diff
changeset
|
825 |
1097
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
826 mapPatterns[i] = r->npatterns; |
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
827 r->patterns[r->npatterns] = m->patterns[i]; |
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
828 (r->npatterns)++; |
0 | 829 } |
1097
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
830 else |
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
831 if (m->patterns[i] != NULL) |
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
832 unused++; |
1094 | 833 |
1097
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
834 dmMsg(1, "%d used patterns (%d unused).\n", |
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
835 r->npatterns, unused); |
1235
5b8245e5f785
Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
1233
diff
changeset
|
836 |
5b8245e5f785
Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
1233
diff
changeset
|
837 |
1094 | 838 // |
0 | 839 // Re-map instruments |
1094 | 840 // |
1097
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
841 dmMsg(1, "Creating sample instrument remaps...\n"); |
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
842 for (unused = n8 = n16 = i = 0; i < jsetMaxInstruments; i++) |
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
843 if (usedInstruments[i]) |
0 | 844 { |
1097
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
845 JSSInstrument *ip; |
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
846 if (optStripInstr) |
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
847 continue; |
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
848 |
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
849 if (i >= m->ninstruments) |
0 | 850 { |
1097
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
851 dmErrorMsg("Instrument 0x%x >= 0x%x, but used!\n", |
1111
f9a96fc2a932
Adjust messages to show user-visible (1 based) instrument numbers.
Matti Hamalainen <ccr@tnsp.org>
parents:
1109
diff
changeset
|
852 i + 1, m->ninstruments); |
1097
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
853 continue; |
0 | 854 } |
1097
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
855 |
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
856 if ((ip = m->instruments[i]) == NULL) |
0 | 857 { |
1111
f9a96fc2a932
Adjust messages to show user-visible (1 based) instrument numbers.
Matti Hamalainen <ccr@tnsp.org>
parents:
1109
diff
changeset
|
858 dmErrorMsg("Instrument 0x%x used but is NULL.\n", i + 1); |
1097
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
859 continue; |
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
860 } |
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
861 |
1111
f9a96fc2a932
Adjust messages to show user-visible (1 based) instrument numbers.
Matti Hamalainen <ccr@tnsp.org>
parents:
1109
diff
changeset
|
862 dmPrint(2, "%02x -> %02x : ", i + 1, r->ninstruments + 1); |
f9a96fc2a932
Adjust messages to show user-visible (1 based) instrument numbers.
Matti Hamalainen <ccr@tnsp.org>
parents:
1109
diff
changeset
|
863 |
1097
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
864 mapInstruments[i] = r->ninstruments; |
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
865 r->instruments[r->ninstruments] = ip; |
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
866 (r->ninstruments)++; |
0 | 867 |
1097
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
868 if (ip->flags & jsf16bit) |
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
869 n16++; |
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
870 else |
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
871 n8++; |
0 | 872 } |
1097
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
873 else |
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
874 if (m->instruments[i] != NULL) |
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
875 unused++; |
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
876 |
0 | 877 dmPrint(2, "\n"); |
1097
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
878 dmMsg(1, "Total of %d [16-bit] + %d [8-bit] samples = %d instruments (%d unused).\n", |
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
879 n16, n8, r->ninstruments, unused); |
1235
5b8245e5f785
Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
1233
diff
changeset
|
880 |
1097
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
881 // |
0 | 882 // Re-map ext.instruments |
1097
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
883 // |
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
884 dmMsg(1, "Creating ext.instrument remaps...\n"); |
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
885 for (unused = i = 0; i < jsetMaxInstruments; i++) |
0 | 886 if (usedExtInstruments[i]) |
887 { | |
1097
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
888 JSSExtInstrument *eip; |
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
889 int note; |
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
890 if (optStripExtInstr) |
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
891 continue; |
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
892 |
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
893 if (i >= m->nextInstruments) |
0 | 894 { |
958
985225a93aeb
Add error code parameter to dmError() and dmErrorVA().
Matti Hamalainen <ccr@tnsp.org>
parents:
860
diff
changeset
|
895 dmErrorMsg("Ext.instrument 0x%x >= 0x%x, but used!\n", |
1111
f9a96fc2a932
Adjust messages to show user-visible (1 based) instrument numbers.
Matti Hamalainen <ccr@tnsp.org>
parents:
1109
diff
changeset
|
896 i + 1, m->nextInstruments); |
1097
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
897 continue; |
0 | 898 } |
1097
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
899 |
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
900 if ((eip = m->extInstruments[i]) == NULL) |
0 | 901 { |
1111
f9a96fc2a932
Adjust messages to show user-visible (1 based) instrument numbers.
Matti Hamalainen <ccr@tnsp.org>
parents:
1109
diff
changeset
|
902 dmErrorMsg("Extended instrument 0x%x used but is NULL.\n", i + 1); |
1097
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
903 continue; |
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
904 } |
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
905 |
1111
f9a96fc2a932
Adjust messages to show user-visible (1 based) instrument numbers.
Matti Hamalainen <ccr@tnsp.org>
parents:
1109
diff
changeset
|
906 dmPrint(2, "%02x -> %02x : ", i + 1, r->nextInstruments + 1); |
f9a96fc2a932
Adjust messages to show user-visible (1 based) instrument numbers.
Matti Hamalainen <ccr@tnsp.org>
parents:
1109
diff
changeset
|
907 |
1097
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
908 mapExtInstruments[i] = r->nextInstruments; |
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
909 r->extInstruments[r->nextInstruments] = eip; |
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
910 (r->nextInstruments)++; |
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
911 |
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
912 // Re-map sNumForNotes table for this ext.instrument |
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
913 for (note = 0; note < jsetNNotes; note++) |
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
914 { |
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
915 int q = eip->sNumForNotes[note]; |
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
916 if (q != jsetNotSet) |
0 | 917 { |
1097
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
918 int map; |
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
919 if (q >= 0 && q < jsetMaxInstruments) |
0 | 920 { |
1097
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
921 map = mapInstruments[q]; |
0 | 922 } |
1097
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
923 else |
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
924 { |
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
925 map = jsetNotSet; |
1111
f9a96fc2a932
Adjust messages to show user-visible (1 based) instrument numbers.
Matti Hamalainen <ccr@tnsp.org>
parents:
1109
diff
changeset
|
926 dmErrorMsg("Einst=%d, note=%d, sNumForNote=%d (%d max)\n", |
f9a96fc2a932
Adjust messages to show user-visible (1 based) instrument numbers.
Matti Hamalainen <ccr@tnsp.org>
parents:
1109
diff
changeset
|
927 i + 1, note, q + 1, r->ninstruments); |
1097
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
928 } |
1111
f9a96fc2a932
Adjust messages to show user-visible (1 based) instrument numbers.
Matti Hamalainen <ccr@tnsp.org>
parents:
1109
diff
changeset
|
929 |
f9a96fc2a932
Adjust messages to show user-visible (1 based) instrument numbers.
Matti Hamalainen <ccr@tnsp.org>
parents:
1109
diff
changeset
|
930 dmPrint(3, "%02x.%02x ", q + 1, map + 1); |
1097
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
931 eip->sNumForNotes[note] = map; |
0 | 932 } |
933 } | |
934 } | |
935 else | |
1097
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
936 if (m->extInstruments[i] != NULL) |
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
937 unused++; |
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
938 |
0 | 939 dmPrint(2, "\n"); |
1097
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
940 dmMsg(1, "%d extended instruments (%d unused).\n", |
0e3cb9e61170
Code cleanup, in preparation for bug hunting.
Matti Hamalainen <ccr@tnsp.org>
parents:
1094
diff
changeset
|
941 r->nextInstruments, unused); |
1094 | 942 |
943 // | |
944 // Remap pattern data with remapped instrument data | |
945 // | |
0 | 946 for (i = 0; i < r->npatterns; i++) |
947 { | |
948 int row, channel; | |
949 JSSPattern *p = r->patterns[i]; | |
950 JSSNote *n = p->data; | |
1235
5b8245e5f785
Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
1233
diff
changeset
|
951 |
0 | 952 for (row = 0; row < p->nrows; row++) |
953 for (channel = 0; channel < p->nchannels; channel++, n++) | |
954 { | |
184
50f55def91e5
Add a minor optimization in the conversion.
Matti Hamalainen <ccr@tnsp.org>
parents:
86
diff
changeset
|
955 char effect; |
50f55def91e5
Add a minor optimization in the conversion.
Matti Hamalainen <ccr@tnsp.org>
parents:
86
diff
changeset
|
956 |
1109 | 957 // If not stripping extended instruments, check for |
958 // the validity of the used instrument and remap | |
338
cd57ba1130eb
Fixes and improvements in the JMOD saving and loading.
Matti Hamalainen <ccr@tnsp.org>
parents:
337
diff
changeset
|
959 if (!optStripExtInstr) |
cd57ba1130eb
Fixes and improvements in the JMOD saving and loading.
Matti Hamalainen <ccr@tnsp.org>
parents:
337
diff
changeset
|
960 { |
856
415cc781e127
Fix some brain farts in instrument remapping.
Matti Hamalainen <ccr@tnsp.org>
parents:
807
diff
changeset
|
961 if (n->instrument >= 0 && n->instrument < jsetMaxInstruments) |
338
cd57ba1130eb
Fixes and improvements in the JMOD saving and loading.
Matti Hamalainen <ccr@tnsp.org>
parents:
337
diff
changeset
|
962 n->instrument = mapExtInstruments[n->instrument]; |
202
85614db5f577
Warn about invalid instruments.
Matti Hamalainen <ccr@tnsp.org>
parents:
184
diff
changeset
|
963 |
1116 | 964 if (n->instrument != jsetNotSet && |
965 r->extInstruments[n->instrument] == NULL) | |
1111
f9a96fc2a932
Adjust messages to show user-visible (1 based) instrument numbers.
Matti Hamalainen <ccr@tnsp.org>
parents:
1109
diff
changeset
|
966 { |
1116 | 967 dmErrorMsg("Non-existing instrument used #%d, INTERNAL ERROR.\n", |
1111
f9a96fc2a932
Adjust messages to show user-visible (1 based) instrument numbers.
Matti Hamalainen <ccr@tnsp.org>
parents:
1109
diff
changeset
|
968 n->instrument + 1); |
f9a96fc2a932
Adjust messages to show user-visible (1 based) instrument numbers.
Matti Hamalainen <ccr@tnsp.org>
parents:
1109
diff
changeset
|
969 } |
338
cd57ba1130eb
Fixes and improvements in the JMOD saving and loading.
Matti Hamalainen <ccr@tnsp.org>
parents:
337
diff
changeset
|
970 } |
cd57ba1130eb
Fixes and improvements in the JMOD saving and loading.
Matti Hamalainen <ccr@tnsp.org>
parents:
337
diff
changeset
|
971 |
184
50f55def91e5
Add a minor optimization in the conversion.
Matti Hamalainen <ccr@tnsp.org>
parents:
86
diff
changeset
|
972 JMPGETEFFECT(effect, n->effect); |
1094 | 973 |
184
50f55def91e5
Add a minor optimization in the conversion.
Matti Hamalainen <ccr@tnsp.org>
parents:
86
diff
changeset
|
974 switch (effect) |
50f55def91e5
Add a minor optimization in the conversion.
Matti Hamalainen <ccr@tnsp.org>
parents:
86
diff
changeset
|
975 { |
50f55def91e5
Add a minor optimization in the conversion.
Matti Hamalainen <ccr@tnsp.org>
parents:
86
diff
changeset
|
976 case 'C': // Cxx = Set volume |
50f55def91e5
Add a minor optimization in the conversion.
Matti Hamalainen <ccr@tnsp.org>
parents:
86
diff
changeset
|
977 if (n->volume == jsetNotSet) |
50f55def91e5
Add a minor optimization in the conversion.
Matti Hamalainen <ccr@tnsp.org>
parents:
86
diff
changeset
|
978 { |
50f55def91e5
Add a minor optimization in the conversion.
Matti Hamalainen <ccr@tnsp.org>
parents:
86
diff
changeset
|
979 n->volume = n->param; |
50f55def91e5
Add a minor optimization in the conversion.
Matti Hamalainen <ccr@tnsp.org>
parents:
86
diff
changeset
|
980 n->effect = jsetNotSet; |
50f55def91e5
Add a minor optimization in the conversion.
Matti Hamalainen <ccr@tnsp.org>
parents:
86
diff
changeset
|
981 n->param = jsetNotSet; |
50f55def91e5
Add a minor optimization in the conversion.
Matti Hamalainen <ccr@tnsp.org>
parents:
86
diff
changeset
|
982 } |
50f55def91e5
Add a minor optimization in the conversion.
Matti Hamalainen <ccr@tnsp.org>
parents:
86
diff
changeset
|
983 break; |
50f55def91e5
Add a minor optimization in the conversion.
Matti Hamalainen <ccr@tnsp.org>
parents:
86
diff
changeset
|
984 } |
0 | 985 } |
986 } | |
1235
5b8245e5f785
Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
1233
diff
changeset
|
987 |
1113
28dcf10fb8a9
Comments, cosmetics, combine one error message.
Matti Hamalainen <ccr@tnsp.org>
parents:
1111
diff
changeset
|
988 // |
0 | 989 // Remap orders list |
1113
28dcf10fb8a9
Comments, cosmetics, combine one error message.
Matti Hamalainen <ccr@tnsp.org>
parents:
1111
diff
changeset
|
990 // |
0 | 991 for (i = 0; i < m->norders; i++) |
992 { | |
993 r->orderList[i] = mapPatterns[m->orderList[i]]; | |
994 } | |
995 | |
996 return r; | |
997 } | |
998 | |
999 | |
1000 int main(int argc, char *argv[]) | |
1001 { | |
730
3d813c81f33c
More work on resources API.
Matti Hamalainen <ccr@tnsp.org>
parents:
652
diff
changeset
|
1002 DMResource *inFile = NULL; |
3d813c81f33c
More work on resources API.
Matti Hamalainen <ccr@tnsp.org>
parents:
652
diff
changeset
|
1003 FILE *outFile = NULL; |
0 | 1004 JSSModule *sm, *dm; |
1005 int result; | |
1006 | |
1007 dmInitProg("xm2jss", "XM to JSSMOD converter", "0.6", NULL, NULL); | |
1008 dmVerbosity = 0; | |
1009 | |
1010 // Parse arguments | |
1011 if (!dmArgsProcess(argc, argv, optList, optListN, | |
860
daebbf28953d
The argument handling API in dmargs* was synced with th-libs.
Matti Hamalainen <ccr@tnsp.org>
parents:
856
diff
changeset
|
1012 argHandleOpt, argHandleFile, OPTH_BAILOUT)) |
0 | 1013 exit(1); |
1014 | |
300 | 1015 // Check arguments |
1016 if (optInFilename == NULL || optOutFilename == NULL) | |
1017 { | |
958
985225a93aeb
Add error code parameter to dmError() and dmErrorVA().
Matti Hamalainen <ccr@tnsp.org>
parents:
860
diff
changeset
|
1018 dmErrorMsg("Input or output file not specified. Try --help.\n"); |
300 | 1019 return 1; |
1020 } | |
0 | 1021 |
1022 // Read the source file | |
730
3d813c81f33c
More work on resources API.
Matti Hamalainen <ccr@tnsp.org>
parents:
652
diff
changeset
|
1023 if ((result = dmf_create_stdio(optInFilename, "rb", &inFile)) != DMERR_OK) |
0 | 1024 { |
958
985225a93aeb
Add error code parameter to dmError() and dmErrorVA().
Matti Hamalainen <ccr@tnsp.org>
parents:
860
diff
changeset
|
1025 dmErrorMsg("Error opening input file '%s', %d: %s\n", |
730
3d813c81f33c
More work on resources API.
Matti Hamalainen <ccr@tnsp.org>
parents:
652
diff
changeset
|
1026 optInFilename, result, dmErrorStr(result)); |
0 | 1027 return 1; |
1028 } | |
1029 | |
1030 // Initialize miniJSS | |
1031 jssInit(); | |
1032 | |
1033 // Read file | |
1034 dmMsg(1, "Reading XM-format file ...\n"); | |
797
f066e9dccf29
Oops, fix some inverted booleans.
Matti Hamalainen <ccr@tnsp.org>
parents:
796
diff
changeset
|
1035 result = jssLoadXM(inFile, &sm, FALSE); |
730
3d813c81f33c
More work on resources API.
Matti Hamalainen <ccr@tnsp.org>
parents:
652
diff
changeset
|
1036 dmf_close(inFile); |
0 | 1037 if (result != 0) |
1038 { | |
1195
4d27c4ec8d4d
Use %d instead of %i in formats.
Matti Hamalainen <ccr@tnsp.org>
parents:
1194
diff
changeset
|
1039 dmErrorMsg("Error while loading XM file (%d), ", result); |
0 | 1040 if (optIgnoreErrors) |
1041 fprintf(stderr, "ignoring. This may cause problems.\n"); | |
1042 else | |
1043 { | |
1044 fprintf(stderr, "giving up. Use --ignore if you want to try to convert anyway.\n"); | |
1045 return 2; | |
1046 } | |
1047 } | |
1048 | |
1049 // Check stripping settings | |
1050 if (optStripExtInstr) optStripInstr = TRUE; | |
1051 if (optStripInstr) optStripSamples = TRUE; | |
1235
5b8245e5f785
Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
1233
diff
changeset
|
1052 |
0 | 1053 // Remove samples |
1054 if (optStripSamples) | |
1055 { | |
1056 int i; | |
1235
5b8245e5f785
Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
1233
diff
changeset
|
1057 |
0 | 1058 dmMsg(1, "Stripping samples...\n"); |
1059 for (i = 0; i < sm->ninstruments; i++) | |
1060 { | |
1061 dmFree(sm->instruments[i]->data); | |
1062 sm->instruments[i]->data = NULL; | |
1063 } | |
1064 } | |
1065 | |
1066 // Remove instruments | |
1067 if (optStripInstr) | |
1068 { | |
1069 int i; | |
1235
5b8245e5f785
Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
1233
diff
changeset
|
1070 |
0 | 1071 dmMsg(1, "Stripping instruments...\n"); |
1072 for (i = 0; i < sm->ninstruments; i++) | |
1073 { | |
1074 dmFree(sm->instruments[i]); | |
1075 sm->instruments[i] = NULL; | |
1076 } | |
1077 sm->ninstruments = 0; | |
1078 } | |
1079 | |
1080 // Remove ext.instruments | |
1081 if (optStripExtInstr) | |
1082 { | |
1083 int i; | |
1235
5b8245e5f785
Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
1233
diff
changeset
|
1084 |
0 | 1085 dmMsg(1, "Stripping ext.instruments...\n"); |
1086 for (i = 0; i < sm->nextInstruments; i++) | |
1087 { | |
1088 dmFree(sm->extInstruments[i]); | |
1089 sm->extInstruments[i] = NULL; | |
1090 } | |
1091 sm->nextInstruments = 0; | |
1092 } | |
1109 | 1093 |
0 | 1094 // Run the optimization procedure |
1095 if (optOptimize) | |
1096 { | |
1097 dmMsg(1, "Optimizing module data...\n"); | |
1098 dm = optimizeModule(sm); | |
1099 } else | |
1100 dm = sm; | |
1101 | |
1102 // Write output file | |
730
3d813c81f33c
More work on resources API.
Matti Hamalainen <ccr@tnsp.org>
parents:
652
diff
changeset
|
1103 if ((outFile = fopen(optOutFilename, "wb")) == NULL) |
0 | 1104 { |
958
985225a93aeb
Add error code parameter to dmError() and dmErrorVA().
Matti Hamalainen <ccr@tnsp.org>
parents:
860
diff
changeset
|
1105 dmErrorMsg("Error creating output file '%s', %d: %s\n", |
300 | 1106 optOutFilename, errno, strerror(errno)); |
0 | 1107 return 1; |
1108 } | |
1109 | |
9
c42ee907de9c
Various improvements in xm2jss output.
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
1110 dmMsg(1, "Writing JSSMOD-format file [patMode=0x%04x, samp8=0x%02x, samp16=0x%02x]\n", |
0 | 1111 optPatternMode, optSampMode8, optSampMode16); |
1235
5b8245e5f785
Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
1233
diff
changeset
|
1112 |
730
3d813c81f33c
More work on resources API.
Matti Hamalainen <ccr@tnsp.org>
parents:
652
diff
changeset
|
1113 result = jssSaveJSSMOD(outFile, dm, optPatternMode, optSampMode8, optSampMode16); |
1113
28dcf10fb8a9
Comments, cosmetics, combine one error message.
Matti Hamalainen <ccr@tnsp.org>
parents:
1111
diff
changeset
|
1114 |
1114
7aaab1533c90
Free the source module data at end.
Matti Hamalainen <ccr@tnsp.org>
parents:
1113
diff
changeset
|
1115 dmFree(sm); |
7aaab1533c90
Free the source module data at end.
Matti Hamalainen <ccr@tnsp.org>
parents:
1113
diff
changeset
|
1116 |
730
3d813c81f33c
More work on resources API.
Matti Hamalainen <ccr@tnsp.org>
parents:
652
diff
changeset
|
1117 fclose(outFile); |
1235
5b8245e5f785
Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
1233
diff
changeset
|
1118 |
0 | 1119 if (result != 0) |
1120 { | |
1113
28dcf10fb8a9
Comments, cosmetics, combine one error message.
Matti Hamalainen <ccr@tnsp.org>
parents:
1111
diff
changeset
|
1121 dmErrorMsg( |
28dcf10fb8a9
Comments, cosmetics, combine one error message.
Matti Hamalainen <ccr@tnsp.org>
parents:
1111
diff
changeset
|
1122 "Error while saving JSSMOD file, %d: %s\n" |
28dcf10fb8a9
Comments, cosmetics, combine one error message.
Matti Hamalainen <ccr@tnsp.org>
parents:
1111
diff
changeset
|
1123 "WARNING: The resulting file may be broken!\n", |
300 | 1124 result, dmErrorStr(result)); |
0 | 1125 } |
300 | 1126 else |
1127 { | |
1128 dmMsg(1, "Conversion complete.\n"); | |
1129 } | |
0 | 1130 return 0; |
1131 } |