comparison src/modplug/load_it.cxx @ 2216:3673c7ec4ea2

Sync with schism's modplug engine. Suggested by G¸«ärkan Seng¸«än.
author William Pitcock <nenolod@atheme.org>
date Fri, 07 Dec 2007 12:08:47 -0600
parents 6b5a52635b3b
children 6907fc39b53f
comparison
equal deleted inserted replaced
2198:32f9f1e4a9ec 2216:3673c7ec4ea2
1 /* 1 /*
2 * This source code is public domain. 2 * This source code is public domain.
3 * 3 *
4 * Authors: Olivier Lapicque <olivierl@jps.net>, 4 * Authors: Olivier Lapicque <olivierl@jps.net>,
5 * Adam Goode <adam@evdebs.org> (Endian and char fixes for PPC) 5 * Adam Goode <adam@evdebs.org> (endian and char fixes for PPC)
6 * Marco Trillo <toad@arsystel.com> (Endian fixes for SaveIT, XM->IT Sample Converter)
7 *
8 */ 6 */
9 7
10 #include "stdafx.h" 8 #include "stdafx.h"
11 #include "sndfile.h" 9 #include "sndfile.h"
12 #include "it_defs.h" 10 #include "it_defs.h"
13 11
12 /* blah, -mrsb.
13 this is a schism header */
14 #include "midi.h"
15
14 #ifdef MSC_VER 16 #ifdef MSC_VER
15 #pragma warning(disable:4244) 17 #pragma warning(disable:4244)
16 #endif 18 #endif
17 19
18 BYTE autovibit2xm[8] = 20 BYTE autovibit2xm[8] =
20 22
21 BYTE autovibxm2it[8] = 23 BYTE autovibxm2it[8] =
22 { 0, 2, 4, 1, 3, 0, 0, 0 }; 24 { 0, 2, 4, 1, 3, 0, 0, 0 };
23 25
24 ////////////////////////////////////////////////////////// 26 //////////////////////////////////////////////////////////
25 // Impulse Tracker IT file support 27 // Impulse Tracker IT file support (import only)
26 28
27 // for conversion of XM samples
28 extern WORD XMPeriodTable[96+8];
29 extern UINT XMLinearTable[768];
30 29
31 static inline UINT ConvertVolParam(UINT value) 30 static inline UINT ConvertVolParam(UINT value)
32 //-------------------------------------------- 31 //--------------------------------------------
33 { 32 {
34 return (value > 9) ? 9 : value; 33 return (value > 9) ? 9 : value;
42 { 41 {
43 const ITOLDINSTRUMENT *pis = (const ITOLDINSTRUMENT *)p; 42 const ITOLDINSTRUMENT *pis = (const ITOLDINSTRUMENT *)p;
44 memcpy(penv->name, pis->name, 26); 43 memcpy(penv->name, pis->name, 26);
45 memcpy(penv->filename, pis->filename, 12); 44 memcpy(penv->filename, pis->filename, 12);
46 penv->nFadeOut = bswapLE16(pis->fadeout) << 6; 45 penv->nFadeOut = bswapLE16(pis->fadeout) << 6;
47 penv->nGlobalVol = 64; 46 penv->nGlobalVol = 128;
48 for (UINT j=0; j<120; j++) 47 for (UINT j=0; j<120; j++)
49 { 48 {
50 UINT note = pis->keyboard[j*2]; 49 UINT note = pis->keyboard[j*2];
51 UINT ins = pis->keyboard[j*2+1]; 50 UINT ins = pis->keyboard[j*2+1];
52 if (ins < MAX_SAMPLES) penv->Keyboard[j] = ins; 51 if (ins < MAX_SAMPLES) penv->Keyboard[j] = ins;
54 else if (note >= 0xFE) penv->NoteMap[j] = note; 53 else if (note >= 0xFE) penv->NoteMap[j] = note;
55 } 54 }
56 if (pis->flags & 0x01) penv->dwFlags |= ENV_VOLUME; 55 if (pis->flags & 0x01) penv->dwFlags |= ENV_VOLUME;
57 if (pis->flags & 0x02) penv->dwFlags |= ENV_VOLLOOP; 56 if (pis->flags & 0x02) penv->dwFlags |= ENV_VOLLOOP;
58 if (pis->flags & 0x04) penv->dwFlags |= ENV_VOLSUSTAIN; 57 if (pis->flags & 0x04) penv->dwFlags |= ENV_VOLSUSTAIN;
59 penv->nVolLoopStart = pis->vls; 58 penv->VolEnv.nLoopStart = pis->vls;
60 penv->nVolLoopEnd = pis->vle; 59 penv->VolEnv.nLoopEnd = pis->vle;
61 penv->nVolSustainBegin = pis->sls; 60 penv->VolEnv.nSustainStart = pis->sls;
62 penv->nVolSustainEnd = pis->sle; 61 penv->VolEnv.nSustainEnd = pis->sle;
63 penv->nVolEnv = 25; 62 penv->VolEnv.nNodes = 25;
64 for (UINT ev=0; ev<25; ev++) 63 for (UINT ev=0; ev<25; ev++)
65 { 64 {
66 if ((penv->VolPoints[ev] = pis->nodes[ev*2]) == 0xFF) 65 if ((penv->VolEnv.Ticks[ev] = pis->nodes[ev*2]) == 0xFF)
67 { 66 {
68 penv->nVolEnv = ev; 67 penv->VolEnv.nNodes = ev;
69 break; 68 break;
70 } 69 }
71 penv->VolEnv[ev] = pis->nodes[ev*2+1]; 70 penv->VolEnv.Values[ev] = pis->nodes[ev*2+1];
72 } 71 }
73 penv->nNNA = pis->nna; 72 penv->nNNA = pis->nna;
74 penv->nDCT = pis->dnc; 73 penv->nDCT = pis->dnc;
75 penv->nPan = 0x80; 74 penv->nPan = 0x80;
76 } else 75 } else
80 memcpy(penv->filename, pis->filename, 12); 79 memcpy(penv->filename, pis->filename, 12);
81 penv->nMidiProgram = pis->mpr; 80 penv->nMidiProgram = pis->mpr;
82 penv->nMidiChannel = pis->mch; 81 penv->nMidiChannel = pis->mch;
83 penv->wMidiBank = bswapLE16(pis->mbank); 82 penv->wMidiBank = bswapLE16(pis->mbank);
84 penv->nFadeOut = bswapLE16(pis->fadeout) << 5; 83 penv->nFadeOut = bswapLE16(pis->fadeout) << 5;
85 penv->nGlobalVol = pis->gbv >> 1; 84 penv->nGlobalVol = pis->gbv;
86 if (penv->nGlobalVol > 64) penv->nGlobalVol = 64; 85 if (penv->nGlobalVol > 128) penv->nGlobalVol = 128;
87 for (UINT j=0; j<120; j++) 86 for (UINT j=0; j<120; j++)
88 { 87 {
89 UINT note = pis->keyboard[j*2]; 88 UINT note = pis->keyboard[j*2];
90 UINT ins = pis->keyboard[j*2+1]; 89 UINT ins = pis->keyboard[j*2+1];
91 if (ins < MAX_SAMPLES) penv->Keyboard[j] = ins; 90 if (ins < MAX_SAMPLES) penv->Keyboard[j] = ins;
95 // Volume Envelope 94 // Volume Envelope
96 if (pis->volenv.flags & 1) penv->dwFlags |= ENV_VOLUME; 95 if (pis->volenv.flags & 1) penv->dwFlags |= ENV_VOLUME;
97 if (pis->volenv.flags & 2) penv->dwFlags |= ENV_VOLLOOP; 96 if (pis->volenv.flags & 2) penv->dwFlags |= ENV_VOLLOOP;
98 if (pis->volenv.flags & 4) penv->dwFlags |= ENV_VOLSUSTAIN; 97 if (pis->volenv.flags & 4) penv->dwFlags |= ENV_VOLSUSTAIN;
99 if (pis->volenv.flags & 8) penv->dwFlags |= ENV_VOLCARRY; 98 if (pis->volenv.flags & 8) penv->dwFlags |= ENV_VOLCARRY;
100 penv->nVolEnv = pis->volenv.num; 99 penv->VolEnv.nNodes = pis->volenv.num;
101 if (penv->nVolEnv > 25) penv->nVolEnv = 25; 100 if (penv->VolEnv.nNodes > 25) penv->VolEnv.nNodes = 25;
102 101
103 penv->nVolLoopStart = pis->volenv.lpb; 102 penv->VolEnv.nLoopStart = pis->volenv.lpb;
104 penv->nVolLoopEnd = pis->volenv.lpe; 103 penv->VolEnv.nLoopEnd = pis->volenv.lpe;
105 penv->nVolSustainBegin = pis->volenv.slb; 104 penv->VolEnv.nSustainStart = pis->volenv.slb;
106 penv->nVolSustainEnd = pis->volenv.sle; 105 penv->VolEnv.nSustainEnd = pis->volenv.sle;
107 // Panning Envelope 106 // Panning Envelope
108 if (pis->panenv.flags & 1) penv->dwFlags |= ENV_PANNING; 107 if (pis->panenv.flags & 1) penv->dwFlags |= ENV_PANNING;
109 if (pis->panenv.flags & 2) penv->dwFlags |= ENV_PANLOOP; 108 if (pis->panenv.flags & 2) penv->dwFlags |= ENV_PANLOOP;
110 if (pis->panenv.flags & 4) penv->dwFlags |= ENV_PANSUSTAIN; 109 if (pis->panenv.flags & 4) penv->dwFlags |= ENV_PANSUSTAIN;
111 if (pis->panenv.flags & 8) penv->dwFlags |= ENV_PANCARRY; 110 if (pis->panenv.flags & 8) penv->dwFlags |= ENV_PANCARRY;
112 penv->nPanEnv = pis->panenv.num; 111 penv->PanEnv.nNodes = pis->panenv.num;
113 if (penv->nPanEnv > 25) penv->nPanEnv = 25; 112 if (penv->PanEnv.nNodes > 25) penv->PanEnv.nNodes = 25;
114 penv->nPanLoopStart = pis->panenv.lpb; 113 penv->PanEnv.nLoopStart = pis->panenv.lpb;
115 penv->nPanLoopEnd = pis->panenv.lpe; 114 penv->PanEnv.nLoopEnd = pis->panenv.lpe;
116 penv->nPanSustainBegin = pis->panenv.slb; 115 penv->PanEnv.nSustainStart = pis->panenv.slb;
117 penv->nPanSustainEnd = pis->panenv.sle; 116 penv->PanEnv.nSustainEnd = pis->panenv.sle;
118 // Pitch Envelope 117 // Pitch Envelope
119 if (pis->pitchenv.flags & 1) penv->dwFlags |= ENV_PITCH; 118 if (pis->pitchenv.flags & 1) penv->dwFlags |= ENV_PITCH;
120 if (pis->pitchenv.flags & 2) penv->dwFlags |= ENV_PITCHLOOP; 119 if (pis->pitchenv.flags & 2) penv->dwFlags |= ENV_PITCHLOOP;
121 if (pis->pitchenv.flags & 4) penv->dwFlags |= ENV_PITCHSUSTAIN; 120 if (pis->pitchenv.flags & 4) penv->dwFlags |= ENV_PITCHSUSTAIN;
122 if (pis->pitchenv.flags & 8) penv->dwFlags |= ENV_PITCHCARRY; 121 if (pis->pitchenv.flags & 8) penv->dwFlags |= ENV_PITCHCARRY;
123 if (pis->pitchenv.flags & 0x80) penv->dwFlags |= ENV_FILTER; 122 if (pis->pitchenv.flags & 0x80) penv->dwFlags |= ENV_FILTER;
124 penv->nPitchEnv = pis->pitchenv.num; 123 penv->PitchEnv.nNodes = pis->pitchenv.num;
125 if (penv->nPitchEnv > 25) penv->nPitchEnv = 25; 124 if (penv->PitchEnv.nNodes > 25) penv->PitchEnv.nNodes = 25;
126 penv->nPitchLoopStart = pis->pitchenv.lpb; 125 penv->PitchEnv.nLoopStart = pis->pitchenv.lpb;
127 penv->nPitchLoopEnd = pis->pitchenv.lpe; 126 penv->PitchEnv.nLoopEnd = pis->pitchenv.lpe;
128 penv->nPitchSustainBegin = pis->pitchenv.slb; 127 penv->PitchEnv.nSustainStart = pis->pitchenv.slb;
129 penv->nPitchSustainEnd = pis->pitchenv.sle; 128 penv->PitchEnv.nSustainEnd = pis->pitchenv.sle;
130 // Envelopes Data 129 // Envelopes Data
131 for (UINT ev=0; ev<25; ev++) 130 for (UINT ev=0; ev<25; ev++)
132 { 131 {
133 penv->VolEnv[ev] = pis->volenv.data[ev*3]; 132 penv->VolEnv.Values[ev] = pis->volenv.data[ev*3];
134 penv->VolPoints[ev] = (pis->volenv.data[ev*3+2] << 8) | (pis->volenv.data[ev*3+1]); 133 penv->VolEnv.Ticks[ev] = (pis->volenv.data[ev*3+2] << 8) | (pis->volenv.data[ev*3+1]);
135 penv->PanEnv[ev] = pis->panenv.data[ev*3] + 32; 134 penv->PanEnv.Values[ev] = pis->panenv.data[ev*3] + 32;
136 penv->PanPoints[ev] = (pis->panenv.data[ev*3+2] << 8) | (pis->panenv.data[ev*3+1]); 135 penv->PanEnv.Ticks[ev] = (pis->panenv.data[ev*3+2] << 8) | (pis->panenv.data[ev*3+1]);
137 penv->PitchEnv[ev] = pis->pitchenv.data[ev*3] + 32; 136 penv->PitchEnv.Values[ev] = pis->pitchenv.data[ev*3] + 32;
138 penv->PitchPoints[ev] = (pis->pitchenv.data[ev*3+2] << 8) | (pis->pitchenv.data[ev*3+1]); 137 penv->PitchEnv.Ticks[ev] = (pis->pitchenv.data[ev*3+2] << 8) | (pis->pitchenv.data[ev*3+1]);
139 } 138 }
140 penv->nNNA = pis->nna; 139 penv->nNNA = pis->nna % 4;
141 penv->nDCT = pis->dct; 140 penv->nDCT = pis->dct % 4;
142 penv->nDNA = pis->dca; 141 penv->nDNA = pis->dca % 3;
143 penv->nPPS = pis->pps; 142 penv->nPPS = pis->pps;
144 penv->nPPC = pis->ppc; 143 penv->nPPC = pis->ppc;
145 penv->nIFC = pis->ifc; 144 penv->nIFC = pis->ifc;
146 penv->nIFR = pis->ifr; 145 penv->nIFR = pis->ifr;
147 penv->nVolSwing = pis->rv; 146 penv->nVolSwing = pis->rv;
148 penv->nPanSwing = pis->rp; 147 penv->nPanSwing = pis->rp;
149 penv->nPan = (pis->dfp & 0x7F) << 2; 148 penv->nPan = (pis->dfp & 0x7F) << 2;
150 if (penv->nPan > 256) penv->nPan = 128; 149 if (penv->nPan > 256) penv->nPan = 128;
151 if (pis->dfp < 0x80) penv->dwFlags |= ENV_SETPANNING; 150 if (pis->dfp < 0x80) penv->dwFlags |= ENV_SETPANNING;
152 } 151 }
153 if ((penv->nVolLoopStart >= 25) || (penv->nVolLoopEnd >= 25)) penv->dwFlags &= ~ENV_VOLLOOP; 152 if ((penv->VolEnv.nLoopStart >= 25) || (penv->VolEnv.nLoopEnd >= 25)) penv->dwFlags &= ~ENV_VOLLOOP;
154 if ((penv->nVolSustainBegin >= 25) || (penv->nVolSustainEnd >= 25)) penv->dwFlags &= ~ENV_VOLSUSTAIN; 153 if ((penv->VolEnv.nSustainStart >= 25) || (penv->VolEnv.nSustainEnd >= 25)) penv->dwFlags &= ~ENV_VOLSUSTAIN;
155 return TRUE; 154 return TRUE;
156 } 155 }
157 156
158 157
159 BOOL CSoundFile::ReadIT(const BYTE *lpStream, DWORD dwMemLength) 158 BOOL CSoundFile::ReadIT(const BYTE *lpStream, DWORD dwMemLength)
165 DWORD smppos[MAX_SAMPLES]; 164 DWORD smppos[MAX_SAMPLES];
166 DWORD patpos[MAX_PATTERNS]; 165 DWORD patpos[MAX_PATTERNS];
167 BYTE chnmask[64], channels_used[64]; 166 BYTE chnmask[64], channels_used[64];
168 MODCOMMAND lastvalue[64]; 167 MODCOMMAND lastvalue[64];
169 168
169 if ((!lpStream) || (dwMemLength < 0xc2)) return FALSE;
170
170 pifh.id = bswapLE32(pifh.id); 171 pifh.id = bswapLE32(pifh.id);
171 pifh.reserved1 = bswapLE16(pifh.reserved1); 172 if (pifh.id == 0x49504D49) {
173 if (dwMemLength < 554) return FALSE;
174
175 WORD tv;
176 INSTRUMENTHEADER *zenv = new INSTRUMENTHEADER;
177 if (!zenv) return FALSE;
178 memset(zenv, 0, sizeof(INSTRUMENTHEADER));
179 memcpy(&tv, lpStream+0x1C, 2); /* trkvers */
180 if (!ITInstrToMPT(lpStream, zenv, tv)) {
181 delete zenv;
182 return FALSE;
183 }
184
185 /* okay, we need samples now */
186 unsigned int q = 554;
187 BYTE expect_samples = lpStream[0x1E];
188
189 m_nType = MOD_TYPE_IT;
190 m_nInstruments = 1;
191 m_nSamples = expect_samples;
192 m_dwSongFlags = SONG_INSTRUMENTMODE | SONG_LINEARSLIDES /* eh? */;
193
194 memcpy(m_szNames[0], lpStream + 0x20, 26);
195 m_szNames[0][26] = 0;
196
197 if (q+(80*expect_samples) >= dwMemLength) {
198 delete zenv;
199 return FALSE;
200 }
201
202 for (UINT nsmp = 0; nsmp < expect_samples; nsmp++) {
203
204 ITSAMPLESTRUCT pis = *(ITSAMPLESTRUCT *)(lpStream+q);
205 q += 80; /* length of ITS header */
206
207 pis.id = bswapLE32(pis.id);
208 pis.length = bswapLE32(pis.length);
209 pis.loopbegin = bswapLE32(pis.loopbegin);
210 pis.loopend = bswapLE32(pis.loopend);
211 pis.C5Speed = bswapLE32(pis.C5Speed);
212 pis.susloopbegin = bswapLE32(pis.susloopbegin);
213 pis.susloopend = bswapLE32(pis.susloopend);
214 pis.samplepointer = bswapLE32(pis.samplepointer);
215
216 if (pis.id == 0x53504D49)
217 {
218 MODINSTRUMENT *pins = &Ins[nsmp+1];
219 memcpy(pins->name, pis.filename, 12);
220 pins->uFlags = 0;
221 pins->nLength = 0;
222 pins->nLoopStart = pis.loopbegin;
223 pins->nLoopEnd = pis.loopend;
224 pins->nSustainStart = pis.susloopbegin;
225 pins->nSustainEnd = pis.susloopend;
226 pins->nC4Speed = pis.C5Speed;
227 if (!pins->nC4Speed) pins->nC4Speed = 8363;
228 //if (pis.C5Speed < 256) pins->nC4Speed = 256;
229 pins->nVolume = pis.vol << 2;
230 if (pins->nVolume > 256) pins->nVolume = 256;
231 pins->nGlobalVol = pis.gvl;
232 if (pins->nGlobalVol > 64) pins->nGlobalVol = 64;
233 if (pis.flags & 0x10) pins->uFlags |= CHN_LOOP;
234 if (pis.flags & 0x20) pins->uFlags |= CHN_SUSTAINLOOP;
235 if (pis.flags & 0x40) pins->uFlags |= CHN_PINGPONGLOOP;
236 if (pis.flags & 0x80) pins->uFlags |= CHN_PINGPONGSUSTAIN;
237 pins->nPan = (pis.dfp & 0x7F) << 2;
238 if (pins->nPan > 256) pins->nPan = 256;
239 if (pis.dfp & 0x80) pins->uFlags |= CHN_PANNING;
240 pins->nVibType = autovibit2xm[pis.vit & 7];
241 pins->nVibRate = pis.vis;
242 pins->nVibDepth = pis.vid & 0x7F;
243 pins->nVibSweep = pis.vir;
244 if ((pis.samplepointer) && (pis.samplepointer < dwMemLength) && (pis.length))
245 {
246 pins->nLength = pis.length;
247 if (pins->nLength > MAX_SAMPLE_LENGTH) pins->nLength = MAX_SAMPLE_LENGTH;
248 UINT flags = (pis.cvt & 1) ? RS_PCM8S : RS_PCM8U;
249 if (pis.flags & 2)
250 {
251 flags += 5;
252 if (pis.flags & 4) flags |= RSF_STEREO;
253 pins->uFlags |= CHN_16BIT;
254 // IT 2.14 16-bit packed sample ?
255 if (pis.flags & 8) flags = ((pifh.cmwt >= 0x215) && (pis.cvt & 4)) ? RS_IT21516 : RS_IT21416;
256 } else
257 {
258 if (pis.flags & 4) flags |= RSF_STEREO;
259 if (pis.cvt == 0xFF) flags = RS_ADPCM4; else
260 // IT 2.14 8-bit packed sample ?
261 if (pis.flags & 8) flags = ((pifh.cmwt >= 0x215) && (pis.cvt & 4)) ? RS_IT2158 : RS_IT2148;
262 }
263 ReadSample(&Ins[nsmp+1], flags, (LPSTR)(lpStream+pis.samplepointer), dwMemLength - pis.samplepointer);
264 }
265 }
266 memcpy(m_szNames[nsmp+1], pis.name, 26);
267
268 }
269
270 Headers[1] = zenv;
271 return TRUE;
272 }
273
274
172 pifh.ordnum = bswapLE16(pifh.ordnum); 275 pifh.ordnum = bswapLE16(pifh.ordnum);
173 pifh.insnum = bswapLE16(pifh.insnum); 276 pifh.insnum = bswapLE16(pifh.insnum);
174 pifh.smpnum = bswapLE16(pifh.smpnum); 277 pifh.smpnum = bswapLE16(pifh.smpnum);
175 pifh.patnum = bswapLE16(pifh.patnum); 278 pifh.patnum = bswapLE16(pifh.patnum);
176 pifh.cwtv = bswapLE16(pifh.cwtv); 279 pifh.cwtv = bswapLE16(pifh.cwtv);
179 pifh.special = bswapLE16(pifh.special); 282 pifh.special = bswapLE16(pifh.special);
180 pifh.msglength = bswapLE16(pifh.msglength); 283 pifh.msglength = bswapLE16(pifh.msglength);
181 pifh.msgoffset = bswapLE32(pifh.msgoffset); 284 pifh.msgoffset = bswapLE32(pifh.msgoffset);
182 pifh.reserved2 = bswapLE32(pifh.reserved2); 285 pifh.reserved2 = bswapLE32(pifh.reserved2);
183 286
184 if ((!lpStream) || (dwMemLength < 0x100)) return FALSE; 287
288
185 if ((pifh.id != 0x4D504D49) || (pifh.insnum >= MAX_INSTRUMENTS) 289 if ((pifh.id != 0x4D504D49) || (pifh.insnum >= MAX_INSTRUMENTS)
186 || (!pifh.smpnum) || (pifh.smpnum >= MAX_INSTRUMENTS) || (!pifh.ordnum)) return FALSE; 290 || (pifh.smpnum >= MAX_INSTRUMENTS)) return FALSE;
187 if (dwMemPos + pifh.ordnum + pifh.insnum*4 291 if (dwMemPos + pifh.ordnum + pifh.insnum*4
188 + pifh.smpnum*4 + pifh.patnum*4 > dwMemLength) return FALSE; 292 + pifh.smpnum*4 + pifh.patnum*4 > dwMemLength) return FALSE;
189 m_nType = MOD_TYPE_IT; 293 m_nType = MOD_TYPE_IT;
294 if (!(pifh.flags & 0x01)) m_dwSongFlags |= SONG_NOSTEREO;
295 if (pifh.flags & 0x04) m_dwSongFlags |= SONG_INSTRUMENTMODE;
190 if (pifh.flags & 0x08) m_dwSongFlags |= SONG_LINEARSLIDES; 296 if (pifh.flags & 0x08) m_dwSongFlags |= SONG_LINEARSLIDES;
191 if (pifh.flags & 0x10) m_dwSongFlags |= SONG_ITOLDEFFECTS; 297 if (pifh.flags & 0x10) m_dwSongFlags |= SONG_ITOLDEFFECTS;
192 if (pifh.flags & 0x20) m_dwSongFlags |= SONG_ITCOMPATMODE; 298 if (pifh.flags & 0x20) m_dwSongFlags |= SONG_ITCOMPATMODE;
299 if (pifh.flags & 0x40) {
300 midi_flags |= MIDI_PITCH_BEND;
301 midi_pitch_depth = pifh.pwd;
302 }
193 if (pifh.flags & 0x80) m_dwSongFlags |= SONG_EMBEDMIDICFG; 303 if (pifh.flags & 0x80) m_dwSongFlags |= SONG_EMBEDMIDICFG;
194 if (pifh.flags & 0x1000) m_dwSongFlags |= SONG_EXFILTERRANGE; 304 if (pifh.flags & 0x1000) m_dwSongFlags |= SONG_EXFILTERRANGE;
195 memcpy(m_szNames[0], pifh.songname, 26); 305 memcpy(m_szNames[0], pifh.songname, 26);
196 m_szNames[0][26] = 0; 306 m_szNames[0][26] = 0;
307 if (pifh.cwtv >= 0x0213) {
308 m_rowHighlightMinor = pifh.hilight_minor;
309 m_rowHighlightMajor = pifh.hilight_major;
310 } else {
311 m_rowHighlightMinor = 4;
312 m_rowHighlightMajor = 16;
313 }
197 // Global Volume 314 // Global Volume
198 if (pifh.globalvol) 315 m_nDefaultGlobalVolume = pifh.globalvol << 1;
199 { 316 if (m_nDefaultGlobalVolume > 256) m_nDefaultGlobalVolume = 256;
200 m_nDefaultGlobalVolume = pifh.globalvol << 1;
201 if (!m_nDefaultGlobalVolume) m_nDefaultGlobalVolume = 256;
202 if (m_nDefaultGlobalVolume > 256) m_nDefaultGlobalVolume = 256;
203 }
204 if (pifh.speed) m_nDefaultSpeed = pifh.speed; 317 if (pifh.speed) m_nDefaultSpeed = pifh.speed;
205 if (pifh.tempo) m_nDefaultTempo = pifh.tempo; 318 if (pifh.tempo) m_nDefaultTempo = pifh.tempo;
206 m_nSongPreAmp = pifh.mv & 0x7F; 319 m_nSongPreAmp = pifh.mv;
320 if (m_nSongPreAmp > 128)
321 m_nSongPreAmp = 128;
322 m_nStereoSeparation = pifh.sep;
207 // Reading Channels Pan Positions 323 // Reading Channels Pan Positions
208 for (int ipan=0; ipan<64; ipan++) if (pifh.chnpan[ipan] != 0xFF) 324 for (int ipan=0; ipan<64; ipan++) if (pifh.chnpan[ipan] != 0xFF)
209 { 325 {
210 ChnSettings[ipan].nVolume = pifh.chnvol[ipan]; 326 ChnSettings[ipan].nVolume = pifh.chnvol[ipan];
211 ChnSettings[ipan].nPan = 128; 327 ChnSettings[ipan].nPan = 128;
227 } 343 }
228 // Reading orders 344 // Reading orders
229 UINT nordsize = pifh.ordnum; 345 UINT nordsize = pifh.ordnum;
230 if (nordsize > MAX_ORDERS) nordsize = MAX_ORDERS; 346 if (nordsize > MAX_ORDERS) nordsize = MAX_ORDERS;
231 memcpy(Order, lpStream+dwMemPos, nordsize); 347 memcpy(Order, lpStream+dwMemPos, nordsize);
348
232 dwMemPos += pifh.ordnum; 349 dwMemPos += pifh.ordnum;
233 // Reading Instrument Offsets 350 // Reading Instrument Offsets
234 memset(inspos, 0, sizeof(inspos)); 351 memset(inspos, 0, sizeof(inspos));
235 UINT inspossize = pifh.insnum; 352 UINT inspossize = pifh.insnum;
236 if (inspossize > MAX_INSTRUMENTS) inspossize = MAX_INSTRUMENTS; 353 if (inspossize > MAX_INSTRUMENTS) inspossize = MAX_INSTRUMENTS;
261 for (UINT j=0; j < (patpossize>>2); j++) 378 for (UINT j=0; j < (patpossize>>2); j++)
262 { 379 {
263 patpos[j] = bswapLE32(patpos[j]); 380 patpos[j] = bswapLE32(patpos[j]);
264 } 381 }
265 dwMemPos += pifh.patnum * 4; 382 dwMemPos += pifh.patnum * 4;
383
384 for (UINT i = 0; i < pifh.ordnum; i++) {
385 if (Order[i] >= pifh.patnum && Order[i] < MAX_PATTERNS) {
386 pifh.patnum = Order[i];
387 for (UINT j = patpossize; j < (unsigned)(pifh.patnum>>2); j++)
388 patpos[j] = 0;
389 patpossize = pifh.patnum;
390 }
391 }
392
393
266 // Reading IT Extra Info 394 // Reading IT Extra Info
267 if (dwMemPos + 2 < dwMemLength) 395 if (dwMemPos + 2 < dwMemLength)
268 { 396 {
269 UINT nflt = bswapLE16(*((WORD *)(lpStream + dwMemPos))); 397 UINT nflt = bswapLE16(*((WORD *)(lpStream + dwMemPos)));
270 dwMemPos += 2; 398 dwMemPos += 2;
275 { 403 {
276 if (dwMemPos + sizeof(MODMIDICFG) < dwMemLength) 404 if (dwMemPos + sizeof(MODMIDICFG) < dwMemLength)
277 { 405 {
278 memcpy(&m_MidiCfg, lpStream+dwMemPos, sizeof(MODMIDICFG)); 406 memcpy(&m_MidiCfg, lpStream+dwMemPos, sizeof(MODMIDICFG));
279 dwMemPos += sizeof(MODMIDICFG); 407 dwMemPos += sizeof(MODMIDICFG);
280 } 408 } else {
281 } 409 ResetMidiCfg();
410 }
411 } else {
412 ResetMidiCfg();
413 }
414 #if 0
282 // Read pattern names: "PNAM" 415 // Read pattern names: "PNAM"
283 if ((dwMemPos + 8 < dwMemLength) && (bswapLE32(*((DWORD *)(lpStream+dwMemPos))) == 0x4d414e50)) 416 if ((dwMemPos + 8 < dwMemLength) && (bswapLE32(*((DWORD *)(lpStream+dwMemPos))) == 0x4d414e50))
284 { 417 {
285 UINT len = bswapLE32(*((DWORD *)(lpStream+dwMemPos+4))); 418 UINT len = bswapLE32(*((DWORD *)(lpStream+dwMemPos+4)));
286 dwMemPos += 8; 419 dwMemPos += 8;
293 memcpy(m_lpszPatternNames, lpStream+dwMemPos, len); 426 memcpy(m_lpszPatternNames, lpStream+dwMemPos, len);
294 } 427 }
295 dwMemPos += len; 428 dwMemPos += len;
296 } 429 }
297 } 430 }
431 #endif
298 // 4-channels minimum 432 // 4-channels minimum
299 m_nChannels = 4; 433 m_nChannels = 4;
434 #if 0
300 // Read channel names: "CNAM" 435 // Read channel names: "CNAM"
301 if ((dwMemPos + 8 < dwMemLength) && (bswapLE32(*((DWORD *)(lpStream+dwMemPos))) == 0x4d414e43)) 436 if ((dwMemPos + 8 < dwMemLength) && (bswapLE32(*((DWORD *)(lpStream+dwMemPos))) == 0x4d414e43))
302 { 437 {
303 UINT len = bswapLE32(*((DWORD *)(lpStream+dwMemPos+4))); 438 UINT len = bswapLE32(*((DWORD *)(lpStream+dwMemPos+4)));
304 dwMemPos += 8; 439 dwMemPos += 8;
317 // Read mix plugins information 452 // Read mix plugins information
318 if (dwMemPos + 8 < dwMemLength) 453 if (dwMemPos + 8 < dwMemLength)
319 { 454 {
320 dwMemPos += LoadMixPlugins(lpStream+dwMemPos, dwMemLength-dwMemPos); 455 dwMemPos += LoadMixPlugins(lpStream+dwMemPos, dwMemLength-dwMemPos);
321 } 456 }
457 #endif
322 // Checking for unused channels 458 // Checking for unused channels
323 UINT npatterns = pifh.patnum; 459 UINT npatterns = pifh.patnum;
324 if (npatterns > MAX_PATTERNS) npatterns = MAX_PATTERNS; 460 if (npatterns > MAX_PATTERNS) npatterns = MAX_PATTERNS;
325 for (UINT patchk=0; patchk<npatterns; patchk++) 461 for (UINT patchk=0; patchk<npatterns; patchk++)
326 { 462 {
364 if (chnmask[ch] & 8) i += 2; 500 if (chnmask[ch] & 8) i += 2;
365 if (i >= len) break; 501 if (i >= len) break;
366 } 502 }
367 } 503 }
368 // Reading Instruments 504 // Reading Instruments
369 m_nInstruments = 0; 505 m_nInstruments = pifh.insnum;
370 if (pifh.flags & 0x04) m_nInstruments = pifh.insnum;
371 if (m_nInstruments >= MAX_INSTRUMENTS) m_nInstruments = MAX_INSTRUMENTS-1; 506 if (m_nInstruments >= MAX_INSTRUMENTS) m_nInstruments = MAX_INSTRUMENTS-1;
372 for (UINT nins=0; nins<m_nInstruments; nins++) 507 for (UINT nins=0; nins<m_nInstruments; nins++)
373 { 508 {
374 if ((inspos[nins] > 0) && (inspos[nins] < dwMemLength - sizeof(ITOLDINSTRUMENT))) 509 if ((inspos[nins] > 0) && (inspos[nins] < dwMemLength - sizeof(ITOLDINSTRUMENT)))
375 { 510 {
405 pins->nLoopEnd = pis.loopend; 540 pins->nLoopEnd = pis.loopend;
406 pins->nSustainStart = pis.susloopbegin; 541 pins->nSustainStart = pis.susloopbegin;
407 pins->nSustainEnd = pis.susloopend; 542 pins->nSustainEnd = pis.susloopend;
408 pins->nC4Speed = pis.C5Speed; 543 pins->nC4Speed = pis.C5Speed;
409 if (!pins->nC4Speed) pins->nC4Speed = 8363; 544 if (!pins->nC4Speed) pins->nC4Speed = 8363;
410 if (pis.C5Speed < 256) pins->nC4Speed = 256; 545 //if (pis.C5Speed < 256) pins->nC4Speed = 256;
411 pins->nVolume = pis.vol << 2; 546 pins->nVolume = pis.vol << 2;
412 if (pins->nVolume > 256) pins->nVolume = 256; 547 if (pins->nVolume > 256) pins->nVolume = 256;
413 pins->nGlobalVol = pis.gvl; 548 pins->nGlobalVol = pis.gvl;
414 if (pins->nGlobalVol > 64) pins->nGlobalVol = 64; 549 if (pins->nGlobalVol > 64) pins->nGlobalVol = 64;
415 if (pis.flags & 0x10) pins->uFlags |= CHN_LOOP; 550 if (pis.flags & 0x10) pins->uFlags |= CHN_LOOP;
420 if (pins->nPan > 256) pins->nPan = 256; 555 if (pins->nPan > 256) pins->nPan = 256;
421 if (pis.dfp & 0x80) pins->uFlags |= CHN_PANNING; 556 if (pis.dfp & 0x80) pins->uFlags |= CHN_PANNING;
422 pins->nVibType = autovibit2xm[pis.vit & 7]; 557 pins->nVibType = autovibit2xm[pis.vit & 7];
423 pins->nVibRate = pis.vis; 558 pins->nVibRate = pis.vis;
424 pins->nVibDepth = pis.vid & 0x7F; 559 pins->nVibDepth = pis.vid & 0x7F;
425 pins->nVibSweep = (pis.vir + 3) / 4; 560 pins->nVibSweep = pis.vir;
426 if ((pis.samplepointer) && (pis.samplepointer < dwMemLength) && (pis.length)) 561 if ((pis.samplepointer) && (pis.samplepointer < dwMemLength) && (pis.length))
427 { 562 {
428 pins->nLength = pis.length; 563 pins->nLength = pis.length;
429 if (pins->nLength > MAX_SAMPLE_LENGTH) pins->nLength = MAX_SAMPLE_LENGTH; 564 if (pins->nLength > MAX_SAMPLE_LENGTH) pins->nLength = MAX_SAMPLE_LENGTH;
430 UINT flags = (pis.cvt & 1) ? RS_PCM8S : RS_PCM8U; 565 UINT flags = (pis.cvt & 1) ? RS_PCM8S : RS_PCM8U;
451 for (UINT npat=0; npat<npatterns; npat++) 586 for (UINT npat=0; npat<npatterns; npat++)
452 { 587 {
453 if ((!patpos[npat]) || ((DWORD)patpos[npat] + 4 >= dwMemLength)) 588 if ((!patpos[npat]) || ((DWORD)patpos[npat] + 4 >= dwMemLength))
454 { 589 {
455 PatternSize[npat] = 64; 590 PatternSize[npat] = 64;
591 PatternAllocSize[npat] = 64;
456 Patterns[npat] = AllocatePattern(64, m_nChannels); 592 Patterns[npat] = AllocatePattern(64, m_nChannels);
457 continue; 593 continue;
458 } 594 }
459 595
460 UINT len = bswapLE16(*((WORD *)(lpStream+patpos[npat]))); 596 UINT len = bswapLE16(*((WORD *)(lpStream+patpos[npat])));
461 UINT rows = bswapLE16(*((WORD *)(lpStream+patpos[npat]+2))); 597 UINT rows = bswapLE16(*((WORD *)(lpStream+patpos[npat]+2)));
462 if ((rows < 4) || (rows > 256)) continue; 598 if ((rows < 4) || (rows > 256)) continue;
463 if (patpos[npat]+8+len > dwMemLength) continue; 599 if (patpos[npat]+8+len > dwMemLength) continue;
464 PatternSize[npat] = rows; 600 PatternSize[npat] = rows;
601 PatternAllocSize[npat] = rows;
465 if ((Patterns[npat] = AllocatePattern(rows, m_nChannels)) == NULL) continue; 602 if ((Patterns[npat] = AllocatePattern(rows, m_nChannels)) == NULL) continue;
466 memset(lastvalue, 0, sizeof(lastvalue)); 603 memset(lastvalue, 0, sizeof(lastvalue));
467 memset(chnmask, 0, sizeof(chnmask)); 604 memset(chnmask, 0, sizeof(chnmask));
468 MODCOMMAND *m = Patterns[npat]; 605 MODCOMMAND *m = Patterns[npat];
469 UINT i = 0; 606 UINT i = 0;
549 // 115-124: Pitch Slide Down 686 // 115-124: Pitch Slide Down
550 if (vol < 125) { m[ch].volcmd = VOLCMD_PORTAUP; m[ch].vol = vol - 115; } else 687 if (vol < 125) { m[ch].volcmd = VOLCMD_PORTAUP; m[ch].vol = vol - 115; } else
551 // 193-202: Portamento To 688 // 193-202: Portamento To
552 if ((vol >= 193) && (vol <= 202)) { m[ch].volcmd = VOLCMD_TONEPORTAMENTO; m[ch].vol = vol - 193; } else 689 if ((vol >= 193) && (vol <= 202)) { m[ch].volcmd = VOLCMD_TONEPORTAMENTO; m[ch].vol = vol - 193; } else
553 // 203-212: Vibrato 690 // 203-212: Vibrato
554 if ((vol >= 203) && (vol <= 212)) { m[ch].volcmd = VOLCMD_VIBRATOSPEED; m[ch].vol = vol - 203; } 691 if ((vol >= 203) && (vol <= 212)) { m[ch].volcmd = VOLCMD_VIBRATO; m[ch].vol = vol - 203; }
555 lastvalue[ch].volcmd = m[ch].volcmd; 692 lastvalue[ch].volcmd = m[ch].volcmd;
556 lastvalue[ch].vol = m[ch].vol; 693 lastvalue[ch].vol = m[ch].vol;
557 } 694 }
558 } 695 }
559 // Reading command/param 696 // Reading command/param
590 } 727 }
591 728
592 729
593 #ifndef MODPLUG_NO_FILESAVE 730 #ifndef MODPLUG_NO_FILESAVE
594 //#define SAVEITTIMESTAMP 731 //#define SAVEITTIMESTAMP
732
733 #ifdef MSC_VER
595 #pragma warning(disable:4100) 734 #pragma warning(disable:4100)
596 735 #endif
736
737 #if 0
597 BOOL CSoundFile::SaveIT(LPCSTR lpszFileName, UINT nPacking) 738 BOOL CSoundFile::SaveIT(LPCSTR lpszFileName, UINT nPacking)
598 //--------------------------------------------------------- 739 //---------------------------------------------------------
599 { 740 {
600 DWORD dwPatNamLen, dwChnNamLen; 741 DWORD dwPatNamLen, dwChnNamLen;
601 ITFILEHEADER header, writeheader; 742 ITFILEHEADER header;
602 ITINSTRUMENT iti, writeiti; 743 ITINSTRUMENT iti;
603 ITSAMPLESTRUCT itss; 744 ITSAMPLESTRUCT itss;
604 BYTE smpcount[MAX_SAMPLES]; 745 BYTE smpcount[MAX_SAMPLES];
605 DWORD inspos[MAX_INSTRUMENTS]; 746 DWORD inspos[MAX_INSTRUMENTS];
606 DWORD patpos[MAX_PATTERNS]; 747 DWORD patpos[MAX_PATTERNS];
607 DWORD smppos[MAX_SAMPLES]; 748 DWORD smppos[MAX_SAMPLES];
619 memset(smppos, 0, sizeof(smppos)); 760 memset(smppos, 0, sizeof(smppos));
620 // Writing Header 761 // Writing Header
621 memset(&header, 0, sizeof(header)); 762 memset(&header, 0, sizeof(header));
622 dwPatNamLen = 0; 763 dwPatNamLen = 0;
623 dwChnNamLen = 0; 764 dwChnNamLen = 0;
624 header.id = 0x4D504D49; // IMPM 765 header.id = 0x4D504D49;
625 lstrcpyn((char *)header.songname, m_szNames[0], 27); 766 lstrcpyn(header.songname, m_szNames[0], 27);
626 header.reserved1 = 0x1004; 767 header.hilight_minor = m_rowHighlightMinor;
768 header.hilight_major = m_rowHighlightMajor;
627 header.ordnum = 0; 769 header.ordnum = 0;
628 while ((header.ordnum < MAX_ORDERS) && (Order[header.ordnum] < 0xFF)) header.ordnum++; 770 while ((header.ordnum < MAX_ORDERS) && (Order[header.ordnum] < 0xFF)) header.ordnum++;
629 if (header.ordnum < MAX_ORDERS) Order[header.ordnum++] = 0xFF; 771 if (header.ordnum < MAX_ORDERS) Order[header.ordnum++] = 0xFF;
630 header.insnum = m_nInstruments; 772 header.insnum = m_nInstruments;
631 header.smpnum = m_nSamples; 773 header.smpnum = m_nSamples;
633 while ((header.patnum > 0) && (!Patterns[header.patnum-1])) header.patnum--; 775 while ((header.patnum > 0) && (!Patterns[header.patnum-1])) header.patnum--;
634 header.cwtv = 0x217; 776 header.cwtv = 0x217;
635 header.cmwt = 0x200; 777 header.cmwt = 0x200;
636 header.flags = 0x0001; 778 header.flags = 0x0001;
637 header.special = 0x0006; 779 header.special = 0x0006;
638 if (m_nInstruments) header.flags |= 0x04; 780 if (m_dwSongFlags & SONG_INSTRUMENTMODE) header.flags |= 0x04;
639 if (m_dwSongFlags & SONG_LINEARSLIDES) header.flags |= 0x08; 781 if (m_dwSongFlags & SONG_LINEARSLIDES) header.flags |= 0x08;
640 if (m_dwSongFlags & SONG_ITOLDEFFECTS) header.flags |= 0x10; 782 if (m_dwSongFlags & SONG_ITOLDEFFECTS) header.flags |= 0x10;
641 if (m_dwSongFlags & SONG_ITCOMPATMODE) header.flags |= 0x20; 783 if (m_dwSongFlags & SONG_ITCOMPATMODE) header.flags |= 0x20;
642 if (m_dwSongFlags & SONG_EXFILTERRANGE) header.flags |= 0x1000; 784 if (m_dwSongFlags & SONG_EXFILTERRANGE) header.flags |= 0x1000;
643 header.globalvol = m_nDefaultGlobalVolume >> 1; 785 header.globalvol = m_nDefaultGlobalVolume >> 1;
644 header.mv = m_nSongPreAmp; 786 header.mv = m_nSongPreAmp;
645 // clip song pre-amp values (between 0x20 and 0x7f)
646 if (header.mv < 0x20) header.mv = 0x20;
647 if (header.mv > 0x7F) header.mv = 0x7F;
648 header.speed = m_nDefaultSpeed; 787 header.speed = m_nDefaultSpeed;
649 header.tempo = m_nDefaultTempo; 788 header.tempo = m_nDefaultTempo;
650 header.sep = m_nStereoSeparation; 789 header.sep = m_nStereoSeparation;
651 dwHdrPos = sizeof(header) + header.ordnum; 790 dwHdrPos = sizeof(header) + header.ordnum;
652 // Channel Pan and Volume 791 // Channel Pan and Volume
689 header.special |= 1; 828 header.special |= 1;
690 header.msglength = strlen(m_lpszSongComments)+1; 829 header.msglength = strlen(m_lpszSongComments)+1;
691 header.msgoffset = dwHdrPos + dwExtra + header.insnum*4 + header.patnum*4 + header.smpnum*4; 830 header.msgoffset = dwHdrPos + dwExtra + header.insnum*4 + header.patnum*4 + header.smpnum*4;
692 } 831 }
693 // Write file header 832 // Write file header
694 memcpy(writeheader, header, sizeof(header)); 833 fwrite(&header, 1, sizeof(header), f);
695
696 // Byteswap header information
697 writeheader.id = bswapLE32(writeheader.id);
698 writeheader.reserved1 = bswapLE16(writeheader.reserved1);
699 writeheader.ordnum = bswapLE16(writeheader.ordnum);
700 writeheader.insnum = bswapLE16(writeheader.insnum);
701 writeheader.smpnum = bswapLE16(writeheader.smpnum);
702 writeheader.patnum = bswapLE16(writeheader.patnum);
703 writeheader.cwtv = bswapLE16(writeheader.cwtv);
704 writeheader.cmwt = bswapLE16(writeheader.cmwt);
705 writeheader.flags = bswapLE16(writeheader.flags);
706 writeheader.special = bswapLE16(writeheader.special);
707 writeheader.msglength = bswapLE16(writeheader.msglength);
708 writeheader.msgoffset = bswapLE32(writeheader.msgoffset);
709 writeheader.reserved2 = bswapLE32(writeheader.reserved2);
710
711 fwrite(&writeheader, 1, sizeof(writeheader), f);
712
713 fwrite(Order, 1, header.ordnum, f); 834 fwrite(Order, 1, header.ordnum, f);
714 if (header.insnum) fwrite(inspos, 4, header.insnum, f); 835 if (header.insnum) fwrite(inspos, 4, header.insnum, f);
715 if (header.smpnum) fwrite(smppos, 4, header.smpnum, f); 836 if (header.smpnum) fwrite(smppos, 4, header.smpnum, f);
716 if (header.patnum) fwrite(patpos, 4, header.patnum, f); 837 if (header.patnum) fwrite(patpos, 4, header.patnum, f);
717 // Writing editor history information 838 // Writing editor history information
738 fwrite(&m_MidiCfg, 1, sizeof(MODMIDICFG), f); 859 fwrite(&m_MidiCfg, 1, sizeof(MODMIDICFG), f);
739 } 860 }
740 // Writing pattern names 861 // Writing pattern names
741 if (dwPatNamLen) 862 if (dwPatNamLen)
742 { 863 {
743 DWORD d = bswapLE32(0x4d414e50); 864 DWORD d = 0x4d414e50;
744 UINT len= bswapLE32(dwPatNamLen);
745 fwrite(&d, 1, 4, f); 865 fwrite(&d, 1, 4, f);
746 write(&len, 1, 4, f); 866 fwrite(&dwPatNamLen, 1, 4, f);
747 fwrite(m_lpszPatternNames, 1, dwPatNamLen, f); 867 fwrite(m_lpszPatternNames, 1, dwPatNamLen, f);
748 } 868 }
749 // Writing channel Names 869 // Writing channel Names
750 if (dwChnNamLen) 870 if (dwChnNamLen)
751 { 871 {
752 DWORD d = bswapLE32(0x4d414e43); 872 DWORD d = 0x4d414e43;
753 UINT len= bswapLE32(dwChnNamLen);
754 fwrite(&d, 1, 4, f); 873 fwrite(&d, 1, 4, f);
755 fwrite(&len, 1, 4, f); 874 fwrite(&dwChnNamLen, 1, 4, f);
756 UINT nChnNames = dwChnNamLen / MAX_CHANNELNAME; 875 UINT nChnNames = dwChnNamLen / MAX_CHANNELNAME;
757 for (UINT inam=0; inam<nChnNames; inam++) 876 for (UINT inam=0; inam<nChnNames; inam++)
758 { 877 {
759 fwrite(ChnSettings[inam].szName, 1, MAX_CHANNELNAME, f); 878 fwrite(ChnSettings[inam].szName, 1, MAX_CHANNELNAME, f);
760 } 879 }
787 iti.dct = penv->nDCT; 906 iti.dct = penv->nDCT;
788 iti.dca = penv->nDNA; 907 iti.dca = penv->nDNA;
789 iti.fadeout = penv->nFadeOut >> 5; 908 iti.fadeout = penv->nFadeOut >> 5;
790 iti.pps = penv->nPPS; 909 iti.pps = penv->nPPS;
791 iti.ppc = penv->nPPC; 910 iti.ppc = penv->nPPC;
792 iti.gbv = (BYTE)(penv->nGlobalVol << 1); 911 iti.gbv = (BYTE)penv->nGlobalVol;
793 iti.dfp = (BYTE)penv->nPan >> 2; 912 iti.dfp = (BYTE)penv->nPan >> 2;
794 if (!(penv->dwFlags & ENV_SETPANNING)) iti.dfp |= 0x80; 913 if (!(penv->dwFlags & ENV_SETPANNING)) iti.dfp |= 0x80;
795 iti.rv = penv->nVolSwing; 914 iti.rv = penv->nVolSwing;
796 iti.rp = penv->nPanSwing; 915 iti.rp = penv->nPanSwing;
797 iti.ifc = penv->nIFC; 916 iti.ifc = penv->nIFC;
811 // Writing Volume envelope 930 // Writing Volume envelope
812 if (penv->dwFlags & ENV_VOLUME) iti.volenv.flags |= 0x01; 931 if (penv->dwFlags & ENV_VOLUME) iti.volenv.flags |= 0x01;
813 if (penv->dwFlags & ENV_VOLLOOP) iti.volenv.flags |= 0x02; 932 if (penv->dwFlags & ENV_VOLLOOP) iti.volenv.flags |= 0x02;
814 if (penv->dwFlags & ENV_VOLSUSTAIN) iti.volenv.flags |= 0x04; 933 if (penv->dwFlags & ENV_VOLSUSTAIN) iti.volenv.flags |= 0x04;
815 if (penv->dwFlags & ENV_VOLCARRY) iti.volenv.flags |= 0x08; 934 if (penv->dwFlags & ENV_VOLCARRY) iti.volenv.flags |= 0x08;
816 iti.volenv.num = (BYTE)penv->nVolEnv; 935 iti.volenv.num = (BYTE)penv->VolEnv.nNodes;
817 iti.volenv.lpb = (BYTE)penv->nVolLoopStart; 936 iti.volenv.lpb = (BYTE)penv->VolEnv.nLoopStart;
818 iti.volenv.lpe = (BYTE)penv->nVolLoopEnd; 937 iti.volenv.lpe = (BYTE)penv->VolEnv.nLoopEnd;
819 iti.volenv.slb = penv->nVolSustainBegin; 938 iti.volenv.slb = penv->VolEnv.nSustainStart;
820 iti.volenv.sle = penv->nVolSustainEnd; 939 iti.volenv.sle = penv->VolEnv.nSustainEnd;
821 // Writing Panning envelope 940 // Writing Panning envelope
822 if (penv->dwFlags & ENV_PANNING) iti.panenv.flags |= 0x01; 941 if (penv->dwFlags & ENV_PANNING) iti.panenv.flags |= 0x01;
823 if (penv->dwFlags & ENV_PANLOOP) iti.panenv.flags |= 0x02; 942 if (penv->dwFlags & ENV_PANLOOP) iti.panenv.flags |= 0x02;
824 if (penv->dwFlags & ENV_PANSUSTAIN) iti.panenv.flags |= 0x04; 943 if (penv->dwFlags & ENV_PANSUSTAIN) iti.panenv.flags |= 0x04;
825 if (penv->dwFlags & ENV_PANCARRY) iti.panenv.flags |= 0x08; 944 if (penv->dwFlags & ENV_PANCARRY) iti.panenv.flags |= 0x08;
826 iti.panenv.num = (BYTE)penv->nPanEnv; 945 iti.panenv.num = (BYTE)penv->PanEnv.nNodes;
827 iti.panenv.lpb = (BYTE)penv->nPanLoopStart; 946 iti.panenv.lpb = (BYTE)penv->PanEnv.nLoopStart;
828 iti.panenv.lpe = (BYTE)penv->nPanLoopEnd; 947 iti.panenv.lpe = (BYTE)penv->PanEnv.nLoopEnd;
829 iti.panenv.slb = penv->nPanSustainBegin; 948 iti.panenv.slb = penv->PanEnv.nSustainStart;
830 iti.panenv.sle = penv->nPanSustainEnd; 949 iti.panenv.sle = penv->PanEnv.nSustainEnd;
831 // Writing Pitch Envelope 950 // Writing Pitch Envelope
832 if (penv->dwFlags & ENV_PITCH) iti.pitchenv.flags |= 0x01; 951 if (penv->dwFlags & ENV_PITCH) iti.pitchenv.flags |= 0x01;
833 if (penv->dwFlags & ENV_PITCHLOOP) iti.pitchenv.flags |= 0x02; 952 if (penv->dwFlags & ENV_PITCHLOOP) iti.pitchenv.flags |= 0x02;
834 if (penv->dwFlags & ENV_PITCHSUSTAIN) iti.pitchenv.flags |= 0x04; 953 if (penv->dwFlags & ENV_PITCHSUSTAIN) iti.pitchenv.flags |= 0x04;
835 if (penv->dwFlags & ENV_PITCHCARRY) iti.pitchenv.flags |= 0x08; 954 if (penv->dwFlags & ENV_PITCHCARRY) iti.pitchenv.flags |= 0x08;
836 if (penv->dwFlags & ENV_FILTER) iti.pitchenv.flags |= 0x80; 955 if (penv->dwFlags & ENV_FILTER) iti.pitchenv.flags |= 0x80;
837 iti.pitchenv.num = (BYTE)penv->nPitchEnv; 956 iti.pitchenv.num = (BYTE)penv->PitchEnv.nNodes;
838 iti.pitchenv.lpb = (BYTE)penv->nPitchLoopStart; 957 iti.pitchenv.lpb = (BYTE)penv->PitchEnv.nLoopStart;
839 iti.pitchenv.lpe = (BYTE)penv->nPitchLoopEnd; 958 iti.pitchenv.lpe = (BYTE)penv->PitchEnv.nLoopEnd;
840 iti.pitchenv.slb = (BYTE)penv->nPitchSustainBegin; 959 iti.pitchenv.slb = (BYTE)penv->PitchEnv.nSustainStart;
841 iti.pitchenv.sle = (BYTE)penv->nPitchSustainEnd; 960 iti.pitchenv.sle = (BYTE)penv->PitchEnv.nSustainEnd;
842 // Writing Envelopes data 961 // Writing Envelopes data
843 for (UINT ev=0; ev<25; ev++) 962 for (UINT ev=0; ev<25; ev++)
844 { 963 {
845 iti.volenv.data[ev*3] = penv->VolEnv[ev]; 964 iti.volenv.data[ev*3] = penv->VolEnv.Values[ev];
846 iti.volenv.data[ev*3+1] = penv->VolPoints[ev] & 0xFF; 965 iti.volenv.data[ev*3+1] = penv->VolEnv.Ticks[ev] & 0xFF;
847 iti.volenv.data[ev*3+2] = penv->VolPoints[ev] >> 8; 966 iti.volenv.data[ev*3+2] = penv->VolEnv.Ticks[ev] >> 8;
848 iti.panenv.data[ev*3] = penv->PanEnv[ev] - 32; 967 iti.panenv.data[ev*3] = penv->PanEnv.Values[ev] - 32;
849 iti.panenv.data[ev*3+1] = penv->PanPoints[ev] & 0xFF; 968 iti.panenv.data[ev*3+1] = penv->PanEnv.Ticks[ev] & 0xFF;
850 iti.panenv.data[ev*3+2] = penv->PanPoints[ev] >> 8; 969 iti.panenv.data[ev*3+2] = penv->PanEnv.Ticks[ev] >> 8;
851 iti.pitchenv.data[ev*3] = penv->PitchEnv[ev] - 32; 970 iti.pitchenv.data[ev*3] = penv->PitchEnv.Values[ev] - 32;
852 iti.pitchenv.data[ev*3+1] = penv->PitchPoints[ev] & 0xFF; 971 iti.pitchenv.data[ev*3+1] = penv->PitchEnv.Ticks[ev] & 0xFF;
853 iti.pitchenv.data[ev*3+2] = penv->PitchPoints[ev] >> 8; 972 iti.pitchenv.data[ev*3+2] = penv->PitchEnv.Ticks[ev] >> 8;
854 } 973 }
855 } else 974 } else
856 // Save Empty Instrument 975 // Save Empty Instrument
857 { 976 {
858 for (UINT i=0; i<120; i++) iti.keyboard[i*2] = i; 977 for (UINT i=0; i<120; i++) iti.keyboard[i*2] = i;
863 } 982 }
864 if (!iti.nos) iti.trkvers = 0; 983 if (!iti.nos) iti.trkvers = 0;
865 // Writing instrument 984 // Writing instrument
866 inspos[nins-1] = dwPos; 985 inspos[nins-1] = dwPos;
867 dwPos += sizeof(ITINSTRUMENT); 986 dwPos += sizeof(ITINSTRUMENT);
868 987 fwrite(&iti, 1, sizeof(ITINSTRUMENT), f);
869 memcpy(&writeiti, &iti, sizeof(ITINSTRUMENT));
870
871 writeiti.fadeout = bswapLE16(writeiti.fadeout);
872 writeiti.id = bswapLE32(writeiti.id);
873 writeiti.trkvers = bswapLE16(writeiti.trkvers);
874 writeiti.mbank = bswapLE16(writeiti.mbank);
875
876 fwrite(&writeiti, 1, sizeof(ITINSTRUMENT), f);
877 } 988 }
878 // Writing sample headers 989 // Writing sample headers
879 memset(&itss, 0, sizeof(itss)); 990 memset(&itss, 0, sizeof(itss));
880 for (UINT hsmp=0; hsmp<header.smpnum; hsmp++) 991 for (UINT hsmp=0; hsmp<header.smpnum; hsmp++)
881 { 992 {
889 DWORD dwPatPos = dwPos; 1000 DWORD dwPatPos = dwPos;
890 UINT len; 1001 UINT len;
891 if (!Patterns[npat]) continue; 1002 if (!Patterns[npat]) continue;
892 patpos[npat] = dwPos; 1003 patpos[npat] = dwPos;
893 patinfo[0] = 0; 1004 patinfo[0] = 0;
894 patinfo[1] = bswapLE16(PatternSize[npat]); 1005 patinfo[1] = PatternSize[npat];
895 patinfo[2] = 0; 1006 patinfo[2] = 0;
896 patinfo[3] = 0; 1007 patinfo[3] = 0;
897 // Check for empty pattern 1008 // Check for empty pattern
898 if (PatternSize[npat] == 64) 1009 if (PatternSize[npat] == 64)
899 { 1010 {
900 MODCOMMAND *pzc = Patterns[npat]; 1011 MODCOMMAND *pzc = Patterns[npat];
901 UINT nz = PatternSize[npat] * m_nChannels; 1012 UINT nz = PatternSize[npat] * m_nChannels;
902 for (UINT iz=0; iz<nz; iz++) 1013 UINT iz;
1014 for (iz=0; iz<nz; iz++)
903 { 1015 {
904 if ((pzc[iz].note) || (pzc[iz].instr) 1016 if ((pzc[iz].note) || (pzc[iz].instr)
905 || (pzc[iz].volcmd) || (pzc[iz].command)) break; 1017 || (pzc[iz].volcmd) || (pzc[iz].command)) break;
906 } 1018 }
907 if (iz == nz) 1019 if (iz == nz)
924 UINT command = m->command; 1036 UINT command = m->command;
925 UINT param = m->param; 1037 UINT param = m->param;
926 UINT vol = 0xFF; 1038 UINT vol = 0xFF;
927 UINT note = m->note; 1039 UINT note = m->note;
928 if (note) b |= 1; 1040 if (note) b |= 1;
929 if ((note) && (note < 0x80)) note--; // 0xfe->0x80 --Toad 1041 if ((note) && (note < 0x80)) note--;
930 if (m->instr) b |= 2; 1042 if (m->instr) b |= 2;
931 if (m->volcmd) 1043 if (m->volcmd)
932 { 1044 {
933 UINT volcmd = m->volcmd; 1045 UINT volcmd = m->volcmd;
934 switch(volcmd) 1046 switch(volcmd)
937 case VOLCMD_PANNING: vol = m->vol + 128; if (vol > 192) vol = 192; break; 1049 case VOLCMD_PANNING: vol = m->vol + 128; if (vol > 192) vol = 192; break;
938 case VOLCMD_VOLSLIDEUP: vol = 85 + ConvertVolParam(m->vol); break; 1050 case VOLCMD_VOLSLIDEUP: vol = 85 + ConvertVolParam(m->vol); break;
939 case VOLCMD_VOLSLIDEDOWN: vol = 95 + ConvertVolParam(m->vol); break; 1051 case VOLCMD_VOLSLIDEDOWN: vol = 95 + ConvertVolParam(m->vol); break;
940 case VOLCMD_FINEVOLUP: vol = 65 + ConvertVolParam(m->vol); break; 1052 case VOLCMD_FINEVOLUP: vol = 65 + ConvertVolParam(m->vol); break;
941 case VOLCMD_FINEVOLDOWN: vol = 75 + ConvertVolParam(m->vol); break; 1053 case VOLCMD_FINEVOLDOWN: vol = 75 + ConvertVolParam(m->vol); break;
942 case VOLCMD_VIBRATOSPEED: vol = 203 + ConvertVolParam(m->vol); break; 1054 case VOLCMD_VIBRATOSPEED: vol = 203; break;
943 case VOLCMD_VIBRATO: vol = 203; break; 1055 case VOLCMD_VIBRATO: vol = 203 + ConvertVolParam(m->vol); break;
944 case VOLCMD_TONEPORTAMENTO: vol = 193 + ConvertVolParam(m->vol); break; 1056 case VOLCMD_TONEPORTAMENTO: vol = 193 + ConvertVolParam(m->vol); break;
945 case VOLCMD_PORTADOWN: vol = 105 + ConvertVolParam(m->vol); break; 1057 case VOLCMD_PORTADOWN: vol = 105 + ConvertVolParam(m->vol); break;
946 case VOLCMD_PORTAUP: vol = 115 + ConvertVolParam(m->vol); break; 1058 case VOLCMD_PORTAUP: vol = 115 + ConvertVolParam(m->vol); break;
947 default: vol = 0xFF; 1059 default: vol = 0xFF;
948 } 1060 }
1032 dwPos += len; 1144 dwPos += len;
1033 patinfo[0] += len; 1145 patinfo[0] += len;
1034 fwrite(buf, 1, len, f); 1146 fwrite(buf, 1, len, f);
1035 } 1147 }
1036 fseek(f, dwPatPos, SEEK_SET); 1148 fseek(f, dwPatPos, SEEK_SET);
1037 patinfo[0] = bswapLE16(patinfo[0]); // byteswap -- Toad
1038 fwrite(patinfo, 8, 1, f); 1149 fwrite(patinfo, 8, 1, f);
1039 fseek(f, dwPos, SEEK_SET); 1150 fseek(f, dwPos, SEEK_SET);
1040 } 1151 }
1041 // Writing Sample Data 1152 // Writing Sample Data
1042 for (UINT nsmp=1; nsmp<=header.smpnum; nsmp++) 1153 for (UINT nsmp=1; nsmp<=header.smpnum; nsmp++)
1045 memset(&itss, 0, sizeof(itss)); 1156 memset(&itss, 0, sizeof(itss));
1046 memcpy(itss.filename, psmp->name, 12); 1157 memcpy(itss.filename, psmp->name, 12);
1047 memcpy(itss.name, m_szNames[nsmp], 26); 1158 memcpy(itss.name, m_szNames[nsmp], 26);
1048 itss.id = 0x53504D49; 1159 itss.id = 0x53504D49;
1049 itss.gvl = (BYTE)psmp->nGlobalVol; 1160 itss.gvl = (BYTE)psmp->nGlobalVol;
1050 if (m_nInstruments) 1161 if (m_dwSongFlags & SONG_INSTRUMENTMODE)
1051 { 1162 {
1052 for (UINT iu=1; iu<=m_nInstruments; iu++) if (Headers[iu]) 1163 for (UINT iu=1; iu<=m_nInstruments; iu++) if (Headers[iu])
1053 { 1164 {
1054 INSTRUMENTHEADER *penv = Headers[iu]; 1165 INSTRUMENTHEADER *penv = Headers[iu];
1055 for (UINT ju=0; ju<128; ju++) if (penv->Keyboard[ju] == nsmp) 1166 for (UINT ju=0; ju<128; ju++) if (penv->Keyboard[ju] == nsmp)
1065 if (psmp->uFlags & CHN_LOOP) itss.flags |= 0x10; 1176 if (psmp->uFlags & CHN_LOOP) itss.flags |= 0x10;
1066 if (psmp->uFlags & CHN_SUSTAINLOOP) itss.flags |= 0x20; 1177 if (psmp->uFlags & CHN_SUSTAINLOOP) itss.flags |= 0x20;
1067 if (psmp->uFlags & CHN_PINGPONGLOOP) itss.flags |= 0x40; 1178 if (psmp->uFlags & CHN_PINGPONGLOOP) itss.flags |= 0x40;
1068 if (psmp->uFlags & CHN_PINGPONGSUSTAIN) itss.flags |= 0x80; 1179 if (psmp->uFlags & CHN_PINGPONGSUSTAIN) itss.flags |= 0x80;
1069 itss.C5Speed = psmp->nC4Speed; 1180 itss.C5Speed = psmp->nC4Speed;
1070 if (!itss.C5Speed) // if no C5Speed assume it is XM Sample 1181 if (!itss.C5Speed) itss.C5Speed = 8363;
1071 {
1072 UINT period;
1073
1074 /**
1075 * C5 note => number 61, but in XM samples:
1076 * RealNote = Note + RelativeTone
1077 */
1078 period = GetPeriodFromNote(61+psmp->RelativeTone, psmp->nFineTune, 0);
1079
1080 if (period)
1081 itss.C5Speed = GetFreqFromPeriod(period, 0, 0);
1082 /**
1083 * If it didn`t work, it may not be a XM file;
1084 * so put the default C5Speed, 8363Hz.
1085 */
1086 if (!itss.C5Speed) itss.C5Speed = 8363;
1087 }
1088
1089 itss.length = psmp->nLength; 1182 itss.length = psmp->nLength;
1090 itss.loopbegin = psmp->nLoopStart; 1183 itss.loopbegin = psmp->nLoopStart;
1091 itss.loopend = psmp->nLoopEnd; 1184 itss.loopend = psmp->nLoopEnd;
1092 itss.susloopbegin = psmp->nSustainStart; 1185 itss.susloopbegin = psmp->nSustainStart;
1093 itss.susloopend = psmp->nSustainEnd; 1186 itss.susloopend = psmp->nSustainEnd;
1094 itss.vol = psmp->nVolume >> 2; 1187 itss.vol = psmp->nVolume >> 2;
1095 itss.dfp = psmp->nPan >> 2; 1188 itss.dfp = psmp->nPan >> 2;
1096 itss.vit = autovibxm2it[psmp->nVibType & 7]; 1189 itss.vit = autovibxm2it[psmp->nVibType & 7];
1097 itss.vis = psmp->nVibRate; 1190 itss.vis = psmp->nVibRate;
1098 itss.vid = psmp->nVibDepth; 1191 itss.vid = psmp->nVibDepth;
1099 itss.vir = (psmp->nVibSweep < 64) ? psmp->nVibSweep * 4 : 255; 1192 itss.vir = psmp->nVibSweep;
1100 if (psmp->uFlags & CHN_PANNING) itss.dfp |= 0x80; 1193 if (psmp->uFlags & CHN_PANNING) itss.dfp |= 0x80;
1101 if ((psmp->pSample) && (psmp->nLength)) itss.cvt = 0x01; 1194 if ((psmp->pSample) && (psmp->nLength)) itss.cvt = 0x01;
1102 UINT flags = RS_PCM8S; 1195 UINT flags = RS_PCM8S;
1103 #ifndef NO_PACKING 1196 #ifndef NO_PACKING
1104 if (nPacking) 1197 if (nPacking)
1105 { 1198 {
1106 if ((!(psmp->uFlags & (CHN_16BIT|CHN_STEREO))) 1199 if ((!(psmp->uFlags & (CHN_16BIT|CHN_STEREO)))
1107 && (CanPackSample((char *)psmp->pSample, psmp->nLength, nPacking))) 1200 && (CanPackSample(psmp->pSample, psmp->nLength, nPacking)))
1108 { 1201 {
1109 flags = RS_ADPCM4; 1202 flags = RS_ADPCM4;
1110 itss.cvt = 0xFF; 1203 itss.cvt = 0xFF;
1111 } 1204 }
1112 } else 1205 } else
1123 flags = (psmp->uFlags & CHN_STEREO) ? RS_STPCM16S : RS_PCM16S; 1216 flags = (psmp->uFlags & CHN_STEREO) ? RS_STPCM16S : RS_PCM16S;
1124 } 1217 }
1125 } 1218 }
1126 itss.samplepointer = dwPos; 1219 itss.samplepointer = dwPos;
1127 fseek(f, smppos[nsmp-1], SEEK_SET); 1220 fseek(f, smppos[nsmp-1], SEEK_SET);
1128
1129 itss.id = bswapLE32(itss.id);
1130 itss.length = bswapLE32(itss.length);
1131 itss.loopbegin = bswapLE32(itss.loopbegin);
1132 itss.loopend = bswapLE32(itss.loopend);
1133 itss.C5Speed = bswapLE32(itss.C5Speed);
1134 itss.susloopbegin = bswapLE32(itss.susloopbegin);
1135 itss.susloopend = bswapLE32(itss.susloopend);
1136 itss.samplepointer = bswapLE32(itss.samplepointer);
1137
1138 fwrite(&itss, 1, sizeof(ITSAMPLESTRUCT), f); 1221 fwrite(&itss, 1, sizeof(ITSAMPLESTRUCT), f);
1139 fseek(f, dwPos, SEEK_SET); 1222 fseek(f, dwPos, SEEK_SET);
1140 if ((psmp->pSample) && (psmp->nLength)) 1223 if ((psmp->pSample) && (psmp->nLength))
1141 { 1224 {
1142 dwPos += WriteSample(f, psmp, flags); 1225 dwPos += WriteSample(f, psmp, flags);
1143 } 1226 }
1144 } 1227 }
1145 // Updating offsets 1228 // Updating offsets
1146 fseek(f, dwHdrPos, SEEK_SET); 1229 fseek(f, dwHdrPos, SEEK_SET);
1147
1148 /* <Toad> Now we can byteswap them ;-) */
1149 UINT WW;
1150 UINT WX;
1151 WX = (UINT)header.insnum;
1152 WX <<= 2;
1153 for (WW=0; WW < (WX>>2); WW++)
1154 inspos[WW] = bswapLE32(inspos[WW]);
1155
1156 WX = (UINT)header.smpnum;
1157 WX <<= 2;
1158 for (WW=0; WW < (WX>>2); WW++)
1159 smppos[WW] = bswapLE32(smppos[WW]);
1160
1161 WX=(UINT)header.patnum;
1162 WX <<= 2;
1163 for (WW=0; WW < (WX>>2); WW++)
1164 patpos[WW] = bswapLE32(patpos[WW]);
1165
1166 if (header.insnum) fwrite(inspos, 4, header.insnum, f); 1230 if (header.insnum) fwrite(inspos, 4, header.insnum, f);
1167 if (header.smpnum) fwrite(smppos, 4, header.smpnum, f); 1231 if (header.smpnum) fwrite(smppos, 4, header.smpnum, f);
1168 if (header.patnum) fwrite(patpos, 4, header.patnum, f); 1232 if (header.patnum) fwrite(patpos, 4, header.patnum, f);
1169 fclose(f); 1233 fclose(f);
1170 return TRUE; 1234 return TRUE;
1171 } 1235 }
1172 1236 #endif
1173 //#pragma warning(default:4100) 1237
1238 #ifdef MSC_VER
1239 #pragma warning(default:4100)
1240 #endif
1241
1174 #endif // MODPLUG_NO_FILESAVE 1242 #endif // MODPLUG_NO_FILESAVE
1175 1243
1176 ////////////////////////////////////////////////////////////////////////////// 1244 //////////////////////////////////////////////////////////////////////////////
1177 // IT 2.14 compression 1245 // IT 2.14 compression
1178 1246
1372 UINT CSoundFile::SaveMixPlugins(FILE *f, BOOL bUpdate) 1440 UINT CSoundFile::SaveMixPlugins(FILE *f, BOOL bUpdate)
1373 //---------------------------------------------------- 1441 //----------------------------------------------------
1374 { 1442 {
1375 DWORD chinfo[64]; 1443 DWORD chinfo[64];
1376 CHAR s[32]; 1444 CHAR s[32];
1377 DWORD nPluginSize, writeSwapDWORD; 1445 DWORD nPluginSize;
1378 SNDMIXPLUGININFO writePluginInfo;
1379 UINT nTotalSize = 0; 1446 UINT nTotalSize = 0;
1380 UINT nChInfo = 0; 1447 UINT nChInfo = 0;
1381 1448
1382 for (UINT i=0; i<MAX_MIXPLUGINS; i++) 1449 for (UINT i=0; i<MAX_MIXPLUGINS; i++)
1383 { 1450 {
1398 s[0] = 'F'; 1465 s[0] = 'F';
1399 s[1] = 'X'; 1466 s[1] = 'X';
1400 s[2] = '0' + (i/10); 1467 s[2] = '0' + (i/10);
1401 s[3] = '0' + (i%10); 1468 s[3] = '0' + (i%10);
1402 fwrite(s, 1, 4, f); 1469 fwrite(s, 1, 4, f);
1403 writeSwapDWORD = bswapLE32(nPluginSize); 1470 fwrite(&nPluginSize, 1, 4, f);
1404 fwrite(&writeSwapDWORD, 1, 4, f); 1471 fwrite(&p->Info, 1, sizeof(SNDMIXPLUGININFO), f);
1405 1472 fwrite(&m_MixPlugins[i].nPluginDataSize, 1, 4, f);
1406 // Copy Information To Be Written for ByteSwapping
1407 memcpy(&writePluginInfo, &p->Info, sizeof(SNDMIXPLUGININFO));
1408 writePluginInfo.dwPluginId1 = bswapLE32(p->Info.dwPluginId1);
1409 writePluginInfo.dwPluginId2 = bswapLE32(p->Info.dwPluginId2);
1410 writePluginInfo.dwInputRouting = bswapLE32(p->Info.dwInputRouting);
1411 writePluginInfo.dwOutputRouting = bswapLE32(p->Info.dwOutputRouting);
1412 for (UINT j=0; j<4; j++)
1413 {
1414 writePluginInfo.dwReserved[j] = bswapLE32(p->Info.dwReserved[j]);
1415 }
1416
1417 fwrite(&writePluginInfo, 1, sizeof(SNDMIXPLUGININFO), f);
1418 writeSwapDWORD = bswapLE32(m_MixPlugins[i].nPluginDataSize);
1419 fwrite(&writeSwapDWORD, 1, 4, f);
1420 if (m_MixPlugins[i].pPluginData) 1473 if (m_MixPlugins[i].pPluginData)
1421 { 1474 {
1422 fwrite(m_MixPlugins[i].pPluginData, 1, m_MixPlugins[i].nPluginDataSize, f); 1475 fwrite(m_MixPlugins[i].pPluginData, 1, m_MixPlugins[i].nPluginDataSize, f);
1423 } 1476 }
1424 } 1477 }
1430 if (j < 64) 1483 if (j < 64)
1431 { 1484 {
1432 if ((chinfo[j] = ChnSettings[j].nMixPlugin) != 0) 1485 if ((chinfo[j] = ChnSettings[j].nMixPlugin) != 0)
1433 { 1486 {
1434 nChInfo = j+1; 1487 nChInfo = j+1;
1435 chinfo[j] = bswapLE32(chinfo[j]); // inplace BS
1436 } 1488 }
1437 } 1489 }
1438 } 1490 }
1439 if (nChInfo) 1491 if (nChInfo)
1440 { 1492 {
1441 if (f) 1493 if (f)
1442 { 1494 {
1443 nPluginSize = bswapLE32(0x58464843); 1495 nPluginSize = 0x58464843;
1444 fwrite(&nPluginSize, 1, 4, f); 1496 fwrite(&nPluginSize, 1, 4, f);
1445 nPluginSize = nChInfo*4; 1497 nPluginSize = nChInfo*4;
1446 writeSwapDWORD = bswapLE32(nPluginSize); 1498 fwrite(&nPluginSize, 1, 4, f);
1447 fwrite(&writeSwapDWORD, 1, 4, f);
1448 fwrite(chinfo, 1, nPluginSize, f); 1499 fwrite(chinfo, 1, nPluginSize, f);
1449 } 1500 }
1450 nTotalSize += nChInfo*4 + 8; 1501 nTotalSize += nChInfo*4 + 8;
1451 } 1502 }
1452 return nTotalSize; 1503 return nTotalSize;