summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--core/multimedia/opieplayer/modplug/load_amf.cpp2
-rw-r--r--core/multimedia/opieplayer/modplug/load_ams.cpp2
-rw-r--r--core/multimedia/opieplayer/modplug/load_mdl.cpp2
3 files changed, 3 insertions, 3 deletions
diff --git a/core/multimedia/opieplayer/modplug/load_amf.cpp b/core/multimedia/opieplayer/modplug/load_amf.cpp
index 188b5f5..2cf131b 100644
--- a/core/multimedia/opieplayer/modplug/load_amf.cpp
+++ b/core/multimedia/opieplayer/modplug/load_amf.cpp
@@ -1,420 +1,420 @@
1/* 1/*
2 * This program is free software; you can redistribute it and modify it 2 * This program is free software; you can redistribute it and modify it
3 * under the terms of the GNU General Public License as published by the 3 * under the terms of the GNU General Public License as published by the
4 * Free Software Foundation; either version 2 of the license or (at your 4 * Free Software Foundation; either version 2 of the license or (at your
5 * option) any later version. 5 * option) any later version.
6 * 6 *
7 * Authors: Olivier Lapicque <olivierl@jps.net> 7 * Authors: Olivier Lapicque <olivierl@jps.net>
8*/ 8*/
9 9
10/////////////////////////////////////////////////// 10///////////////////////////////////////////////////
11// 11//
12// AMF module loader 12// AMF module loader
13// 13//
14// There is 2 types of AMF files: 14// There is 2 types of AMF files:
15// - ASYLUM Music Format 15// - ASYLUM Music Format
16// - Advanced Music Format(DSM) 16// - Advanced Music Format(DSM)
17// 17//
18/////////////////////////////////////////////////// 18///////////////////////////////////////////////////
19#include "stdafx.h" 19#include "stdafx.h"
20#include "sndfile.h" 20#include "sndfile.h"
21 21
22//#define AMFLOG 22//#define AMFLOG
23 23
24//#pragma warning(disable:4244) 24//#pragma warning(disable:4244)
25 25
26#pragma pack(1) 26#pragma pack(1)
27 27
28typedef struct _AMFFILEHEADER 28typedef struct _AMFFILEHEADER
29{ 29{
30 UCHAR szAMF[3]; 30 UCHAR szAMF[3];
31 UCHAR version; 31 UCHAR version;
32 CHAR title[32]; 32 CHAR title[32];
33 UCHAR numsamples; 33 UCHAR numsamples;
34 UCHAR numorders; 34 UCHAR numorders;
35 USHORT numtracks; 35 USHORT numtracks;
36 UCHAR numchannels; 36 UCHAR numchannels;
37} Q_PACKED AMFFILEHEADER; 37} Q_PACKED AMFFILEHEADER;
38 38
39typedef struct _AMFSAMPLE 39typedef struct _AMFSAMPLE
40{ 40{
41 UCHAR type; 41 UCHAR type;
42 CHAR samplename[32]; 42 CHAR samplename[32];
43 CHAR filename[13]; 43 CHAR filename[13];
44 ULONG offset; 44 ULONG offset;
45 ULONG length; 45 ULONG length;
46 USHORT c2spd; 46 USHORT c2spd;
47 UCHAR volume; 47 UCHAR volume;
48} Q_PACKED AMFSAMPLE; 48} Q_PACKED AMFSAMPLE;
49 49
50 50
51#pragma pack() 51#pragma pack()
52 52
53 53
54#ifdef AMFLOG 54#ifdef AMFLOG
55extern void Log(LPCSTR, ...); 55extern void Log(LPCSTR, ...);
56#endif 56#endif
57 57
58VOID AMF_Unpack(MODCOMMAND *pPat, const BYTE *pTrack, UINT nRows, UINT nChannels) 58VOID AMF_Unpack(MODCOMMAND *pPat, const BYTE *pTrack, UINT nRows, UINT nChannels)
59//------------------------------------------------------------------------------- 59//-------------------------------------------------------------------------------
60{ 60{
61 UINT lastinstr = 0; 61 UINT lastinstr = 0;
62 UINT nTrkSize = *(USHORT *)pTrack; 62 UINT nTrkSize = *(USHORT *)pTrack;
63 nTrkSize += (UINT)pTrack[2] << 16; 63 nTrkSize += (UINT)pTrack[2] << 16;
64 pTrack += 3; 64 pTrack += 3;
65 while (nTrkSize--) 65 while (nTrkSize--)
66 { 66 {
67 UINT row = pTrack[0]; 67 UINT row = pTrack[0];
68 UINT cmd = pTrack[1]; 68 UINT cmd = pTrack[1];
69 UINT arg = pTrack[2]; 69 UINT arg = pTrack[2];
70 if (row >= nRows) break; 70 if (row >= nRows) break;
71 MODCOMMAND *m = pPat + row * nChannels; 71 MODCOMMAND *m = pPat + row * nChannels;
72 if (cmd < 0x7F) // note+vol 72 if (cmd < 0x7F) // note+vol
73 { 73 {
74 m->note = cmd+1; 74 m->note = cmd+1;
75 if (!m->instr) m->instr = lastinstr; 75 if (!m->instr) m->instr = lastinstr;
76 m->volcmd = VOLCMD_VOLUME; 76 m->volcmd = VOLCMD_VOLUME;
77 m->vol = arg; 77 m->vol = arg;
78 } else 78 } else
79 if (cmd == 0x7F) // duplicate row 79 if (cmd == 0x7F) // duplicate row
80 { 80 {
81 signed char rdelta = (signed char)arg; 81 signed char rdelta = (signed char)arg;
82 int rowsrc = (int)row + (int)rdelta; 82 int rowsrc = (int)row + (int)rdelta;
83 if ((rowsrc >= 0) && (rowsrc < (int)nRows)) *m = pPat[rowsrc*nChannels]; 83 if ((rowsrc >= 0) && (rowsrc < (int)nRows)) *m = pPat[rowsrc*nChannels];
84 } else 84 } else
85 if (cmd == 0x80) // instrument 85 if (cmd == 0x80) // instrument
86 { 86 {
87 m->instr = arg+1; 87 m->instr = arg+1;
88 lastinstr = m->instr; 88 lastinstr = m->instr;
89 } else 89 } else
90 if (cmd == 0x83) // volume 90 if (cmd == 0x83) // volume
91 { 91 {
92 m->volcmd = VOLCMD_VOLUME; 92 m->volcmd = VOLCMD_VOLUME;
93 m->vol = arg; 93 m->vol = arg;
94 } else 94 } else
95 // effect 95 // effect
96 { 96 {
97 UINT command = cmd & 0x7F; 97 UINT command = cmd & 0x7F;
98 UINT param = arg; 98 UINT param = arg;
99 switch(command) 99 switch(command)
100 { 100 {
101 // 0x01: Set Speed 101 // 0x01: Set Speed
102 case 0x01:command = CMD_SPEED; break; 102 case 0x01:command = CMD_SPEED; break;
103 // 0x02: Volume Slide 103 // 0x02: Volume Slide
104 // 0x0A: Tone Porta + Vol Slide 104 // 0x0A: Tone Porta + Vol Slide
105 // 0x0B: Vibrato + Vol Slide 105 // 0x0B: Vibrato + Vol Slide
106 case 0x02:command = CMD_VOLUMESLIDE; 106 case 0x02:command = CMD_VOLUMESLIDE;
107 case 0x0A:if (command == 0x0A) command = CMD_TONEPORTAVOL; 107 case 0x0A:if (command == 0x0A) command = CMD_TONEPORTAVOL;
108 case 0x0B:if (command == 0x0B) command = CMD_VIBRATOVOL; 108 case 0x0B:if (command == 0x0B) command = CMD_VIBRATOVOL;
109 if (param & 0x80) param = (-(signed char)param)&0x0F; 109 if (param & 0x80) param = (-(signed char)param)&0x0F;
110 else param = (param&0x0F)<<4; 110 else param = (param&0x0F)<<4;
111 break; 111 break;
112 // 0x04: Porta Up/Down 112 // 0x04: Porta Up/Down
113 case 0x04:if (param & 0x80) { command = CMD_PORTAMENTOUP; param = -(signed char)param; } 113 case 0x04:if (param & 0x80) { command = CMD_PORTAMENTOUP; param = -(signed char)param; }
114 else { command = CMD_PORTAMENTODOWN; } break; 114 else { command = CMD_PORTAMENTODOWN; } break;
115 // 0x06: Tone Portamento 115 // 0x06: Tone Portamento
116 case 0x06:command = CMD_TONEPORTAMENTO; break; 116 case 0x06:command = CMD_TONEPORTAMENTO; break;
117 // 0x07: Tremor 117 // 0x07: Tremor
118 case 0x07:command = CMD_TREMOR; break; 118 case 0x07:command = CMD_TREMOR; break;
119 // 0x08: Arpeggio 119 // 0x08: Arpeggio
120 case 0x08:command = CMD_ARPEGGIO; break; 120 case 0x08:command = CMD_ARPEGGIO; break;
121 // 0x09: Vibrato 121 // 0x09: Vibrato
122 case 0x09:command = CMD_VIBRATO; break; 122 case 0x09:command = CMD_VIBRATO; break;
123 // 0x0C: Pattern Break 123 // 0x0C: Pattern Break
124 case 0x0C:command = CMD_PATTERNBREAK; break; 124 case 0x0C:command = CMD_PATTERNBREAK; break;
125 // 0x0D: Position Jump 125 // 0x0D: Position Jump
126 case 0x0D:command = CMD_POSITIONJUMP; break; 126 case 0x0D:command = CMD_POSITIONJUMP; break;
127 // 0x0F: Retrig 127 // 0x0F: Retrig
128 case 0x0F:command = CMD_RETRIG; break; 128 case 0x0F:command = CMD_RETRIG; break;
129 // 0x10: Offset 129 // 0x10: Offset
130 case 0x10:command = CMD_OFFSET; break; 130 case 0x10:command = CMD_OFFSET; break;
131 // 0x11: Fine Volume Slide 131 // 0x11: Fine Volume Slide
132 case 0x11:if (param) { command = CMD_VOLUMESLIDE; 132 case 0x11:if (param) { command = CMD_VOLUMESLIDE;
133 if (param & 0x80) param = 0xF0|((-(signed char)param)&0x0F); 133 if (param & 0x80) param = 0xF0|((-(signed char)param)&0x0F);
134 else param = 0x0F|((param&0x0F)<<4); 134 else param = 0x0F|((param&0x0F)<<4);
135 } else command = 0; break; 135 } else command = 0; break;
136 // 0x12: Fine Portamento 136 // 0x12: Fine Portamento
137 // 0x16: Extra Fine Portamento 137 // 0x16: Extra Fine Portamento
138 case 0x12: 138 case 0x12:
139 case 0x16:if (param) { int mask = (command == 0x16) ? 0xE0 : 0xF0; 139 case 0x16:if (param) { int mask = (command == 0x16) ? 0xE0 : 0xF0;
140 command = (param & 0x80) ? CMD_PORTAMENTOUP : CMD_PORTAMENTODOWN; 140 command = (param & 0x80) ? CMD_PORTAMENTOUP : CMD_PORTAMENTODOWN;
141 if (param & 0x80) param = mask|((-(signed char)param)&0x0F); 141 if (param & 0x80) param = mask|((-(signed char)param)&0x0F);
142 else param |= mask; 142 else param |= mask;
143 } else command = 0; break; 143 } else command = 0; break;
144 // 0x13: Note Delay 144 // 0x13: Note Delay
145 case 0x13:command = CMD_S3MCMDEX; param = 0xD0|(param & 0x0F); break; 145 case 0x13:command = CMD_S3MCMDEX; param = 0xD0|(param & 0x0F); break;
146 // 0x14: Note Cut 146 // 0x14: Note Cut
147 case 0x14:command = CMD_S3MCMDEX; param = 0xC0|(param & 0x0F); break; 147 case 0x14:command = CMD_S3MCMDEX; param = 0xC0|(param & 0x0F); break;
148 // 0x15: Set Tempo 148 // 0x15: Set Tempo
149 case 0x15:command = CMD_TEMPO; break; 149 case 0x15:command = CMD_TEMPO; break;
150 // 0x17: Panning 150 // 0x17: Panning
151 case 0x17:param = (param+64)&0x7F; 151 case 0x17:param = (param+64)&0x7F;
152 if (m->command) { if (!m->volcmd) { m->volcmd = VOLCMD_PANNING; m->vol = param/2; } command = 0; } 152 if (m->command) { if (!m->volcmd) { m->volcmd = VOLCMD_PANNING; m->vol = param/2; } command = 0; }
153 else { command = CMD_PANNING8; } 153 else { command = CMD_PANNING8; }
154 // Unknown effects 154 // Unknown effects
155 default:command = param = 0; 155 default:command = param = 0;
156 } 156 }
157 if (command) 157 if (command)
158 { 158 {
159 m->command = command; 159 m->command = command;
160 m->param = param; 160 m->param = param;
161 } 161 }
162 } 162 }
163 pTrack += 3; 163 pTrack += 3;
164 } 164 }
165} 165}
166 166
167 167
168 168
169BOOL CSoundFile::ReadAMF(LPCBYTE lpStream, DWORD dwMemLength) 169BOOL CSoundFile::ReadAMF(LPCBYTE lpStream, DWORD dwMemLength)
170//----------------------------------------------------------- 170//-----------------------------------------------------------
171{ 171{
172 AMFFILEHEADER *pfh = (AMFFILEHEADER *)lpStream; 172 AMFFILEHEADER *pfh = (AMFFILEHEADER *)lpStream;
173 DWORD dwMemPos; 173 DWORD dwMemPos;
174 174
175 if ((!lpStream) || (dwMemLength < 2048)) return FALSE; 175 if ((!lpStream) || (dwMemLength < 2048)) return FALSE;
176 if ((!strncmp((LPCTSTR)lpStream, "ASYLUM Music Format V1.0", 25)) && (dwMemLength > 4096)) 176 if ((!strncmp((LPCTSTR)lpStream, "ASYLUM Music Format V1.0", 25)) && (dwMemLength > 4096))
177 { 177 {
178 UINT numorders, numpats, numsamples; 178 UINT numorders, numpats, numsamples;
179 179
180 dwMemPos = 32; 180 dwMemPos = 32;
181 numpats = lpStream[dwMemPos+3]; 181 numpats = lpStream[dwMemPos+3];
182 numorders = lpStream[dwMemPos+4]; 182 numorders = lpStream[dwMemPos+4];
183 numsamples = 64; 183 numsamples = 64;
184 dwMemPos += 6; 184 dwMemPos += 6;
185 if ((!numpats) || (numpats > MAX_PATTERNS) || (!numorders) 185 if ((!numpats) || (numpats > MAX_PATTERNS) || (!numorders)
186 || (numpats*64*32 + 294 + 37*64 >= dwMemLength)) return FALSE; 186 || (numpats*64*32 + 294 + 37*64 >= dwMemLength)) return FALSE;
187 m_nType = MOD_TYPE_AMF0; 187 m_nType = MOD_TYPE_AMF0;
188 m_nChannels = 8; 188 m_nChannels = 8;
189 m_nInstruments = 0; 189 m_nInstruments = 0;
190 m_nSamples = 31; 190 m_nSamples = 31;
191 m_nDefaultTempo = 125; 191 m_nDefaultTempo = 125;
192 m_nDefaultSpeed = 6; 192 m_nDefaultSpeed = 6;
193 for (UINT iOrd=0; iOrd<MAX_ORDERS; iOrd++) 193 for (UINT iOrd=0; iOrd<MAX_ORDERS; iOrd++)
194 { 194 {
195 Order[iOrd] = (iOrd < numorders) ? lpStream[dwMemPos+iOrd] : 0xFF; 195 Order[iOrd] = (iOrd < numorders) ? lpStream[dwMemPos+iOrd] : 0xFF;
196 } 196 }
197 dwMemPos = 294; // ??? 197 dwMemPos = 294; // ???
198 for (UINT iSmp=0; iSmp<numsamples; iSmp++) 198 for (UINT iSmp=0; iSmp<numsamples; iSmp++)
199 { 199 {
200 MODINSTRUMENT *psmp = &Ins[iSmp+1]; 200 MODINSTRUMENT *psmp = &Ins[iSmp+1];
201 memcpy(m_szNames[iSmp+1], lpStream+dwMemPos, 22); 201 memcpy(m_szNames[iSmp+1], lpStream+dwMemPos, 22);
202 psmp->nFineTune = MOD2XMFineTune(lpStream[dwMemPos+22]); 202 psmp->nFineTune = MOD2XMFineTune(lpStream[dwMemPos+22]);
203 psmp->nVolume = lpStream[dwMemPos+23]; 203 psmp->nVolume = lpStream[dwMemPos+23];
204 psmp->nGlobalVol = 64; 204 psmp->nGlobalVol = 64;
205 if (psmp->nVolume > 0x40) psmp->nVolume = 0x40; 205 if (psmp->nVolume > 0x40) psmp->nVolume = 0x40;
206 psmp->nVolume <<= 2; 206 psmp->nVolume <<= 2;
207 psmp->nLength = *((LPDWORD)(lpStream+dwMemPos+25)); 207 psmp->nLength = *((LPDWORD)(lpStream+dwMemPos+25));
208 psmp->nLoopStart = *((LPDWORD)(lpStream+dwMemPos+29)); 208 psmp->nLoopStart = *((LPDWORD)(lpStream+dwMemPos+29));
209 psmp->nLoopEnd = psmp->nLoopStart + *((LPDWORD)(lpStream+dwMemPos+33)); 209 psmp->nLoopEnd = psmp->nLoopStart + *((LPDWORD)(lpStream+dwMemPos+33));
210 if ((psmp->nLoopEnd > psmp->nLoopStart) && (psmp->nLoopEnd <= psmp->nLength)) 210 if ((psmp->nLoopEnd > psmp->nLoopStart) && (psmp->nLoopEnd <= psmp->nLength))
211 { 211 {
212 psmp->uFlags = CHN_LOOP; 212 psmp->uFlags = CHN_LOOP;
213 } else 213 } else
214 { 214 {
215 psmp->nLoopStart = psmp->nLoopEnd = 0; 215 psmp->nLoopStart = psmp->nLoopEnd = 0;
216 } 216 }
217 if ((psmp->nLength) && (iSmp>31)) m_nSamples = iSmp+1; 217 if ((psmp->nLength) && (iSmp>31)) m_nSamples = iSmp+1;
218 dwMemPos += 37; 218 dwMemPos += 37;
219 } 219 }
220 for (UINT iPat=0; iPat<numpats; iPat++) 220 for (UINT iPat=0; iPat<numpats; iPat++)
221 { 221 {
222 MODCOMMAND *p = AllocatePattern(64, m_nChannels); 222 MODCOMMAND *p = AllocatePattern(64, m_nChannels);
223 if (!p) break; 223 if (!p) break;
224 Patterns[iPat] = p; 224 Patterns[iPat] = p;
225 PatternSize[iPat] = 64; 225 PatternSize[iPat] = 64;
226 const UCHAR *pin = lpStream + dwMemPos; 226 const UCHAR *pin = lpStream + dwMemPos;
227 for (UINT i=0; i<8*64; i++) 227 for (UINT i=0; i<8*64; i++)
228 { 228 {
229 p->note = 0; 229 p->note = 0;
230 230
231 if (pin[0]) 231 if (pin[0])
232 { 232 {
233 p->note = pin[0] + 13; 233 p->note = pin[0] + 13;
234 } 234 }
235 p->instr = pin[1]; 235 p->instr = pin[1];
236 p->command = pin[2]; 236 p->command = pin[2];
237 p->param = pin[3]; 237 p->param = pin[3];
238 if (p->command > 0x0F) 238 if (p->command > 0x0F)
239 { 239 {
240 #ifdef AMFLOG 240 #ifdef AMFLOG
241 Log("0x%02X.0x%02X ?", p->command, p->param); 241 Log("0x%02X.0x%02X ?", p->command, p->param);
242 #endif 242 #endif
243 p->command = 0; 243 p->command = 0;
244 } 244 }
245 ConvertModCommand(p); 245 ConvertModCommand(p);
246 pin += 4; 246 pin += 4;
247 p++; 247 p++;
248 } 248 }
249 dwMemPos += 64*32; 249 dwMemPos += 64*32;
250 } 250 }
251 // Read samples 251 // Read samples
252 for (UINT iData=0; iData<m_nSamples; iData++) 252 for (UINT iData=0; iData<m_nSamples; iData++)
253 { 253 {
254 MODINSTRUMENT *psmp = &Ins[iData+1]; 254 MODINSTRUMENT *psmp = &Ins[iData+1];
255 if (psmp->nLength) 255 if (psmp->nLength)
256 { 256 {
257 dwMemPos += ReadSample(psmp, RS_PCM8S, (LPCSTR)(lpStream+dwMemPos), dwMemLength); 257 dwMemPos += ReadSample(psmp, RS_PCM8S, (LPCSTR)(lpStream+dwMemPos), dwMemLength);
258 } 258 }
259 } 259 }
260 return TRUE; 260 return TRUE;
261 } 261 }
262 //////////////////////////// 262 ////////////////////////////
263 // DSM/AMF 263 // DSM/AMF
264 USHORT *ptracks[MAX_PATTERNS]; 264 USHORT *ptracks[MAX_PATTERNS];
265 DWORD sampleseekpos[MAX_SAMPLES]; 265 DWORD sampleseekpos[MAX_SAMPLES];
266 266
267 if ((pfh->szAMF[0] != 'A') || (pfh->szAMF[1] != 'M') || (pfh->szAMF[2] != 'F') 267 if ((pfh->szAMF[0] != 'A') || (pfh->szAMF[1] != 'M') || (pfh->szAMF[2] != 'F')
268 || (pfh->version < 10) || (pfh->version > 14) || (!pfh->numtracks) 268 || (pfh->version < 10) || (pfh->version > 14) || (!pfh->numtracks)
269 || (!pfh->numorders) || (pfh->numorders > MAX_PATTERNS) 269 || (!pfh->numorders) || (pfh->numorders > MAX_PATTERNS)
270 || (!pfh->numsamples) || (pfh->numsamples > MAX_SAMPLES) 270 || (!pfh->numsamples) || (pfh->numsamples > MAX_SAMPLES)
271 || (pfh->numchannels < 4) || (pfh->numchannels > 32)) 271 || (pfh->numchannels < 4) || (pfh->numchannels > 32))
272 return FALSE; 272 return FALSE;
273 memcpy(m_szNames[0], pfh->title, 32); 273 memcpy(m_szNames[0], pfh->title, 32);
274 dwMemPos = sizeof(AMFFILEHEADER); 274 dwMemPos = sizeof(AMFFILEHEADER);
275 m_nType = MOD_TYPE_AMF; 275 m_nType = MOD_TYPE_AMF;
276 m_nChannels = pfh->numchannels; 276 m_nChannels = pfh->numchannels;
277 m_nSamples = pfh->numsamples; 277 m_nSamples = pfh->numsamples;
278 m_nInstruments = 0; 278 m_nInstruments = 0;
279 // Setup Channel Pan Positions 279 // Setup Channel Pan Positions
280 if (pfh->version >= 11) 280 if (pfh->version >= 11)
281 { 281 {
282 signed char *panpos = (signed char *)(lpStream + dwMemPos); 282 signed char *panpos = (signed char *)(lpStream + dwMemPos);
283 UINT nchannels = (pfh->version >= 13) ? 32 : 16; 283 UINT nchannels = (pfh->version >= 13) ? 32 : 16;
284 for (UINT i=0; i<nchannels; i++) 284 for (UINT i=0; i<nchannels; i++)
285 { 285 {
286 int pan = (panpos[i] + 64) * 2; 286 int pan = (panpos[i] + 64) * 2;
287 if (pan < 0) pan = 0; 287 if (pan < 0) pan = 0;
288 if (pan > 256) { pan = 128; ChnSettings[i].dwFlags |= CHN_SURROUND; } 288 if (pan > 256) { pan = 128; ChnSettings[i].dwFlags |= CHN_SURROUND; }
289 ChnSettings[i].nPan = pan; 289 ChnSettings[i].nPan = pan;
290 } 290 }
291 dwMemPos += nchannels; 291 dwMemPos += nchannels;
292 } else 292 } else
293 { 293 {
294 for (UINT i=0; i<16; i++) 294 for (UINT i=0; i<16; i++)
295 { 295 {
296 ChnSettings[i].nPan = (lpStream[dwMemPos+i] & 1) ? 0x30 : 0xD0; 296 ChnSettings[i].nPan = (lpStream[dwMemPos+i] & 1) ? 0x30 : 0xD0;
297 } 297 }
298 dwMemPos += 16; 298 dwMemPos += 16;
299 } 299 }
300 // Get Tempo/Speed 300 // Get Tempo/Speed
301 m_nDefaultTempo = 125; 301 m_nDefaultTempo = 125;
302 m_nDefaultSpeed = 6; 302 m_nDefaultSpeed = 6;
303 if (pfh->version >= 13) 303 if (pfh->version >= 13)
304 { 304 {
305 if (lpStream[dwMemPos] >= 32) m_nDefaultTempo = lpStream[dwMemPos]; 305 if (lpStream[dwMemPos] >= 32) m_nDefaultTempo = lpStream[dwMemPos];
306 if (lpStream[dwMemPos+1] <= 32) m_nDefaultSpeed = lpStream[dwMemPos+1]; 306 if (lpStream[dwMemPos+1] <= 32) m_nDefaultSpeed = lpStream[dwMemPos+1];
307 dwMemPos += 2; 307 dwMemPos += 2;
308 } 308 }
309 // Setup sequence list 309 // Setup sequence list
310 for (UINT iOrd=0; iOrd<MAX_ORDERS; iOrd++) 310 for (UINT iOrd=0; iOrd<MAX_ORDERS; iOrd++)
311 { 311 {
312 Order[iOrd] = 0xFF; 312 Order[iOrd] = 0xFF;
313 if (iOrd < pfh->numorders) 313 if (iOrd < pfh->numorders)
314 { 314 {
315 Order[iOrd] = iOrd; 315 Order[iOrd] = iOrd;
316 PatternSize[iOrd] = 64; 316 PatternSize[iOrd] = 64;
317 if (pfh->version >= 14) 317 if (pfh->version >= 14)
318 { 318 {
319 PatternSize[iOrd] = *(USHORT *)(lpStream+dwMemPos); 319 PatternSize[iOrd] = *(USHORT *)(lpStream+dwMemPos);
320 dwMemPos += 2; 320 dwMemPos += 2;
321 } 321 }
322 ptracks[iOrd] = (USHORT *)(lpStream+dwMemPos); 322 ptracks[iOrd] = (USHORT *)(lpStream+dwMemPos);
323 dwMemPos += m_nChannels * sizeof(USHORT); 323 dwMemPos += m_nChannels * sizeof(USHORT);
324 } 324 }
325 } 325 }
326 if (dwMemPos + m_nSamples * (sizeof(AMFSAMPLE)+8) > dwMemLength) return TRUE; 326 if (dwMemPos + m_nSamples * (sizeof(AMFSAMPLE)+8) > dwMemLength) return TRUE;
327 // Read Samples 327 // Read Samples
328 UINT maxsampleseekpos = 0; 328 UINT maxsampleseekpos = 0;
329 for (UINT iIns=0; iIns<m_nSamples; iIns++) 329 for (UINT iIns=0; iIns<m_nSamples; iIns++)
330 { 330 {
331 MODINSTRUMENT *pins = &Ins[iIns+1]; 331 MODINSTRUMENT *pins = &Ins[iIns+1];
332 AMFSAMPLE *psh = (AMFSAMPLE *)(lpStream + dwMemPos); 332 AMFSAMPLE *psh = (AMFSAMPLE *)(lpStream + dwMemPos);
333 333
334 dwMemPos += sizeof(AMFSAMPLE); 334 dwMemPos += sizeof(AMFSAMPLE);
335 memcpy(m_szNames[iIns+1], psh->samplename, 32); 335 memcpy(m_szNames[iIns+1], psh->samplename, 32);
336 memcpy(pins->name, psh->filename, 13); 336 memcpy(pins->name, psh->filename, 13);
337 pins->nLength = psh->length; 337 pins->nLength = psh->length;
338 pins->nC4Speed = psh->c2spd; 338 pins->nC4Speed = psh->c2spd;
339 pins->nGlobalVol = 64; 339 pins->nGlobalVol = 64;
340 pins->nVolume = psh->volume * 4; 340 pins->nVolume = psh->volume * 4;
341 if (pfh->version >= 11) 341 if (pfh->version >= 11)
342 { 342 {
343 pins->nLoopStart = *(DWORD *)(lpStream+dwMemPos); 343 pins->nLoopStart = *(DWORD *)(lpStream+dwMemPos);
344 pins->nLoopEnd = *(DWORD *)(lpStream+dwMemPos+4); 344 pins->nLoopEnd = *(DWORD *)(lpStream+dwMemPos+4);
345 dwMemPos += 8; 345 dwMemPos += 8;
346 } else 346 } else
347 { 347 {
348 pins->nLoopStart = *(WORD *)(lpStream+dwMemPos); 348 pins->nLoopStart = *(WORD *)(lpStream+dwMemPos);
349 pins->nLoopEnd = pins->nLength; 349 pins->nLoopEnd = pins->nLength;
350 dwMemPos += 2; 350 dwMemPos += 2;
351 } 351 }
352 sampleseekpos[iIns] = 0; 352 sampleseekpos[iIns] = 0;
353 if ((psh->type) && (psh->offset < dwMemLength-1)) 353 if ((psh->type) && (psh->offset < dwMemLength-1))
354 { 354 {
355 sampleseekpos[iIns] = psh->offset; 355 sampleseekpos[iIns] = psh->offset;
356 if (psh->offset > maxsampleseekpos) maxsampleseekpos = psh->offset; 356 if (psh->offset > maxsampleseekpos) maxsampleseekpos = psh->offset;
357 if ((pins->nLoopEnd > pins->nLoopStart + 2) 357 if ((pins->nLoopEnd > pins->nLoopStart + 2)
358 && (pins->nLoopEnd <= pins->nLength)) pins->uFlags |= CHN_LOOP; 358 && (pins->nLoopEnd <= pins->nLength)) pins->uFlags |= CHN_LOOP;
359 } 359 }
360 } 360 }
361 // Read Track Mapping Table 361 // Read Track Mapping Table
362 USHORT *pTrackMap = (USHORT *)(lpStream+dwMemPos); 362 USHORT *pTrackMap = (USHORT *)(lpStream+dwMemPos);
363 UINT realtrackcnt = 0; 363 UINT realtrackcnt = 0;
364 dwMemPos += pfh->numtracks * sizeof(USHORT); 364 dwMemPos += pfh->numtracks * sizeof(USHORT);
365 for (UINT iTrkMap=0; iTrkMap<pfh->numtracks; iTrkMap++) 365 for (UINT iTrkMap=0; iTrkMap<pfh->numtracks; iTrkMap++)
366 { 366 {
367 if (realtrackcnt < pTrackMap[iTrkMap]) realtrackcnt = pTrackMap[iTrkMap]; 367 if (realtrackcnt < pTrackMap[iTrkMap]) realtrackcnt = pTrackMap[iTrkMap];
368 } 368 }
369 // Store tracks positions 369 // Store tracks positions
370 BYTE **pTrackData = new BYTE *[realtrackcnt]; 370 BYTE **pTrackData = new BYTE *[realtrackcnt];
371 memset(pTrackData, 0, sizeof(pTrackData)); 371 memset(pTrackData, 0, sizeof(pTrackData));
372 for (UINT iTrack=0; iTrack<realtrackcnt; iTrack++) if (dwMemPos + 3 <= dwMemLength) 372 for (UINT iTrack=0; iTrack<realtrackcnt; iTrack++) if (dwMemPos + 3 <= dwMemLength)
373 { 373 {
374 UINT nTrkSize = *(USHORT *)(lpStream+dwMemPos); 374 UINT nTrkSize = *(USHORT *)(lpStream+dwMemPos);
375 nTrkSize += (UINT)lpStream[dwMemPos+2] << 16; 375 nTrkSize += (UINT)lpStream[dwMemPos+2] << 16;
376 if (dwMemPos + nTrkSize * 3 + 3 <= dwMemLength) 376 if (dwMemPos + nTrkSize * 3 + 3 <= dwMemLength)
377 { 377 {
378 pTrackData[iTrack] = (BYTE *)(lpStream + dwMemPos); 378 pTrackData[iTrack] = (BYTE *)(lpStream + dwMemPos);
379 } 379 }
380 dwMemPos += nTrkSize * 3 + 3; 380 dwMemPos += nTrkSize * 3 + 3;
381 } 381 }
382 // Create the patterns from the list of tracks 382 // Create the patterns from the list of tracks
383 for (UINT iPat=0; iPat<pfh->numorders; iPat++) 383 for (UINT iPat=0; iPat<pfh->numorders; iPat++)
384 { 384 {
385 MODCOMMAND *p = AllocatePattern(PatternSize[iPat], m_nChannels); 385 MODCOMMAND *p = AllocatePattern(PatternSize[iPat], m_nChannels);
386 if (!p) break; 386 if (!p) break;
387 Patterns[iPat] = p; 387 Patterns[iPat] = p;
388 for (UINT iChn=0; iChn<m_nChannels; iChn++) 388 for (UINT iChn=0; iChn<m_nChannels; iChn++)
389 { 389 {
390 UINT nTrack = ptracks[iPat][iChn]; 390 UINT nTrack = ptracks[iPat][iChn];
391 if ((nTrack) && (nTrack <= pfh->numtracks)) 391 if ((nTrack) && (nTrack <= pfh->numtracks))
392 { 392 {
393 UINT realtrk = pTrackMap[nTrack-1]; 393 UINT realtrk = pTrackMap[nTrack-1];
394 if (realtrk) 394 if (realtrk)
395 { 395 {
396 realtrk--; 396 realtrk--;
397 if ((realtrk < realtrackcnt) && (pTrackData[realtrk])) 397 if ((realtrk < realtrackcnt) && (pTrackData[realtrk]))
398 { 398 {
399 AMF_Unpack(p+iChn, pTrackData[realtrk], PatternSize[iPat], m_nChannels); 399 AMF_Unpack(p+iChn, pTrackData[realtrk], PatternSize[iPat], m_nChannels);
400 } 400 }
401 } 401 }
402 } 402 }
403 } 403 }
404 } 404 }
405 delete pTrackData; 405 delete [] pTrackData;
406 // Read Sample Data 406 // Read Sample Data
407 for (UINT iSeek=1; iSeek<=maxsampleseekpos; iSeek++) 407 for (UINT iSeek=1; iSeek<=maxsampleseekpos; iSeek++)
408 { 408 {
409 if (dwMemPos >= dwMemLength) break; 409 if (dwMemPos >= dwMemLength) break;
410 for (UINT iSmp=0; iSmp<m_nSamples; iSmp++) if (iSeek == sampleseekpos[iSmp]) 410 for (UINT iSmp=0; iSmp<m_nSamples; iSmp++) if (iSeek == sampleseekpos[iSmp])
411 { 411 {
412 MODINSTRUMENT *pins = &Ins[iSmp+1]; 412 MODINSTRUMENT *pins = &Ins[iSmp+1];
413 dwMemPos += ReadSample(pins, RS_PCM8U, (LPCSTR)(lpStream+dwMemPos), dwMemLength-dwMemPos); 413 dwMemPos += ReadSample(pins, RS_PCM8U, (LPCSTR)(lpStream+dwMemPos), dwMemLength-dwMemPos);
414 break; 414 break;
415 } 415 }
416 } 416 }
417 return TRUE; 417 return TRUE;
418} 418}
419 419
420 420
diff --git a/core/multimedia/opieplayer/modplug/load_ams.cpp b/core/multimedia/opieplayer/modplug/load_ams.cpp
index 3dd1c2b..ad1cc01 100644
--- a/core/multimedia/opieplayer/modplug/load_ams.cpp
+++ b/core/multimedia/opieplayer/modplug/load_ams.cpp
@@ -1,631 +1,631 @@
1/* 1/*
2 * This program is free software; you can redistribute it and modify it 2 * This program is free software; you can redistribute it and modify it
3 * under the terms of the GNU General Public License as published by the 3 * under the terms of the GNU General Public License as published by the
4 * Free Software Foundation; either version 2 of the license or (at your 4 * Free Software Foundation; either version 2 of the license or (at your
5 * option) any later version. 5 * option) any later version.
6 * 6 *
7 * Authors: Olivier Lapicque <olivierl@jps.net> 7 * Authors: Olivier Lapicque <olivierl@jps.net>
8*/ 8*/
9 9
10////////////////////////////////////////////// 10//////////////////////////////////////////////
11// AMS module loader // 11// AMS module loader //
12////////////////////////////////////////////// 12//////////////////////////////////////////////
13#include "stdafx.h" 13#include "stdafx.h"
14#include "sndfile.h" 14#include "sndfile.h"
15 15
16//#pragma warning(disable:4244) 16//#pragma warning(disable:4244)
17 17
18#pragma pack(1) 18#pragma pack(1)
19 19
20typedef struct AMSFILEHEADER 20typedef struct AMSFILEHEADER
21{ 21{
22 char szHeader[7];// "Extreme" // changed from CHAR 22 char szHeader[7];// "Extreme" // changed from CHAR
23 BYTE verlo, verhi;// 0x??,0x01 23 BYTE verlo, verhi;// 0x??,0x01
24 BYTE chncfg; 24 BYTE chncfg;
25 BYTE samples; 25 BYTE samples;
26 WORD patterns; 26 WORD patterns;
27 WORD orders; 27 WORD orders;
28 BYTE vmidi; 28 BYTE vmidi;
29 WORD extra; 29 WORD extra;
30} Q_PACKED AMSFILEHEADER; 30} Q_PACKED AMSFILEHEADER;
31 31
32typedef struct AMSSAMPLEHEADER 32typedef struct AMSSAMPLEHEADER
33{ 33{
34 DWORD length; 34 DWORD length;
35 DWORD loopstart; 35 DWORD loopstart;
36 DWORD loopend; 36 DWORD loopend;
37 BYTE finetune_and_pan; 37 BYTE finetune_and_pan;
38 WORD samplerate;// C-2 = 8363 38 WORD samplerate;// C-2 = 8363
39 BYTE volume; // 0-127 39 BYTE volume; // 0-127
40 BYTE infobyte; 40 BYTE infobyte;
41} Q_PACKED AMSSAMPLEHEADER; 41} Q_PACKED AMSSAMPLEHEADER;
42 42
43 43
44#pragma pack() 44#pragma pack()
45 45
46 46
47 47
48BOOL CSoundFile::ReadAMS(LPCBYTE lpStream, DWORD dwMemLength) 48BOOL CSoundFile::ReadAMS(LPCBYTE lpStream, DWORD dwMemLength)
49//----------------------------------------------------------- 49//-----------------------------------------------------------
50{ 50{
51 BYTE pkinf[MAX_SAMPLES]; 51 BYTE pkinf[MAX_SAMPLES];
52 AMSFILEHEADER *pfh = (AMSFILEHEADER *)lpStream; 52 AMSFILEHEADER *pfh = (AMSFILEHEADER *)lpStream;
53 DWORD dwMemPos; 53 DWORD dwMemPos;
54 UINT tmp, tmp2; 54 UINT tmp, tmp2;
55 55
56 if ((!lpStream) || (dwMemLength < 1024)) return FALSE; 56 if ((!lpStream) || (dwMemLength < 1024)) return FALSE;
57 if ((pfh->verhi != 0x01) || (strncmp(pfh->szHeader, "Extreme", 7)) 57 if ((pfh->verhi != 0x01) || (strncmp(pfh->szHeader, "Extreme", 7))
58 || (!pfh->patterns) || (!pfh->orders) || (!pfh->samples) || (pfh->samples > MAX_SAMPLES) 58 || (!pfh->patterns) || (!pfh->orders) || (!pfh->samples) || (pfh->samples > MAX_SAMPLES)
59 || (pfh->patterns > MAX_PATTERNS) || (pfh->orders > MAX_ORDERS)) 59 || (pfh->patterns > MAX_PATTERNS) || (pfh->orders > MAX_ORDERS))
60 { 60 {
61 return ReadAMS2(lpStream, dwMemLength); 61 return ReadAMS2(lpStream, dwMemLength);
62 } 62 }
63 dwMemPos = sizeof(AMSFILEHEADER) + pfh->extra; 63 dwMemPos = sizeof(AMSFILEHEADER) + pfh->extra;
64 if (dwMemPos + pfh->samples * sizeof(AMSSAMPLEHEADER) + 256 >= dwMemLength) return FALSE; 64 if (dwMemPos + pfh->samples * sizeof(AMSSAMPLEHEADER) + 256 >= dwMemLength) return FALSE;
65 m_nType = MOD_TYPE_AMS; 65 m_nType = MOD_TYPE_AMS;
66 m_nInstruments = 0; 66 m_nInstruments = 0;
67 m_nChannels = (pfh->chncfg & 0x1F) + 1; 67 m_nChannels = (pfh->chncfg & 0x1F) + 1;
68 m_nSamples = pfh->samples; 68 m_nSamples = pfh->samples;
69 for (UINT nSmp=1; nSmp<=m_nSamples; nSmp++, dwMemPos += sizeof(AMSSAMPLEHEADER)) 69 for (UINT nSmp=1; nSmp<=m_nSamples; nSmp++, dwMemPos += sizeof(AMSSAMPLEHEADER))
70 { 70 {
71 AMSSAMPLEHEADER *psh = (AMSSAMPLEHEADER *)(lpStream + dwMemPos); 71 AMSSAMPLEHEADER *psh = (AMSSAMPLEHEADER *)(lpStream + dwMemPos);
72 MODINSTRUMENT *pins = &Ins[nSmp]; 72 MODINSTRUMENT *pins = &Ins[nSmp];
73 pins->nLength = psh->length; 73 pins->nLength = psh->length;
74 pins->nLoopStart = psh->loopstart; 74 pins->nLoopStart = psh->loopstart;
75 pins->nLoopEnd = psh->loopend; 75 pins->nLoopEnd = psh->loopend;
76 pins->nGlobalVol = 64; 76 pins->nGlobalVol = 64;
77 pins->nVolume = psh->volume << 1; 77 pins->nVolume = psh->volume << 1;
78 pins->nC4Speed = psh->samplerate; 78 pins->nC4Speed = psh->samplerate;
79 pins->nPan = (psh->finetune_and_pan & 0xF0); 79 pins->nPan = (psh->finetune_and_pan & 0xF0);
80 if (pins->nPan < 0x80) pins->nPan += 0x10; 80 if (pins->nPan < 0x80) pins->nPan += 0x10;
81 pins->nFineTune = MOD2XMFineTune(psh->finetune_and_pan & 0x0F); 81 pins->nFineTune = MOD2XMFineTune(psh->finetune_and_pan & 0x0F);
82 pins->uFlags = (psh->infobyte & 0x80) ? CHN_16BIT : 0; 82 pins->uFlags = (psh->infobyte & 0x80) ? CHN_16BIT : 0;
83 if ((pins->nLoopEnd <= pins->nLength) && (pins->nLoopStart+4 <= pins->nLoopEnd)) pins->uFlags |= CHN_LOOP; 83 if ((pins->nLoopEnd <= pins->nLength) && (pins->nLoopStart+4 <= pins->nLoopEnd)) pins->uFlags |= CHN_LOOP;
84 pkinf[nSmp] = psh->infobyte; 84 pkinf[nSmp] = psh->infobyte;
85 } 85 }
86 // Read Song Name 86 // Read Song Name
87 tmp = lpStream[dwMemPos++]; 87 tmp = lpStream[dwMemPos++];
88 if (dwMemPos + tmp + 1 >= dwMemLength) return TRUE; 88 if (dwMemPos + tmp + 1 >= dwMemLength) return TRUE;
89 tmp2 = (tmp < 32) ? tmp : 31; 89 tmp2 = (tmp < 32) ? tmp : 31;
90 if (tmp2) memcpy(m_szNames[0], lpStream+dwMemPos, tmp2); 90 if (tmp2) memcpy(m_szNames[0], lpStream+dwMemPos, tmp2);
91 m_szNames[0][tmp2] = 0; 91 m_szNames[0][tmp2] = 0;
92 dwMemPos += tmp; 92 dwMemPos += tmp;
93 // Read sample names 93 // Read sample names
94 for (UINT sNam=1; sNam<=m_nSamples; sNam++) 94 for (UINT sNam=1; sNam<=m_nSamples; sNam++)
95 { 95 {
96 if (dwMemPos + 32 >= dwMemLength) return TRUE; 96 if (dwMemPos + 32 >= dwMemLength) return TRUE;
97 tmp = lpStream[dwMemPos++]; 97 tmp = lpStream[dwMemPos++];
98 tmp2 = (tmp < 32) ? tmp : 31; 98 tmp2 = (tmp < 32) ? tmp : 31;
99 if (tmp2) memcpy(m_szNames[sNam], lpStream+dwMemPos, tmp2); 99 if (tmp2) memcpy(m_szNames[sNam], lpStream+dwMemPos, tmp2);
100 dwMemPos += tmp; 100 dwMemPos += tmp;
101 } 101 }
102 // Skip Channel names 102 // Skip Channel names
103 for (UINT cNam=0; cNam<m_nChannels; cNam++) 103 for (UINT cNam=0; cNam<m_nChannels; cNam++)
104 { 104 {
105 if (dwMemPos + 32 >= dwMemLength) return TRUE; 105 if (dwMemPos + 32 >= dwMemLength) return TRUE;
106 tmp = lpStream[dwMemPos++]; 106 tmp = lpStream[dwMemPos++];
107 dwMemPos += tmp; 107 dwMemPos += tmp;
108 } 108 }
109 // Read Pattern Names 109 // Read Pattern Names
110 m_lpszPatternNames = new char[pfh->patterns * 32]; // changed from CHAR 110 m_lpszPatternNames = new char[pfh->patterns * 32]; // changed from CHAR
111 if (!m_lpszPatternNames) return TRUE; 111 if (!m_lpszPatternNames) return TRUE;
112 m_nPatternNames = pfh->patterns; 112 m_nPatternNames = pfh->patterns;
113 memset(m_lpszPatternNames, 0, m_nPatternNames * 32); 113 memset(m_lpszPatternNames, 0, m_nPatternNames * 32);
114 for (UINT pNam=0; pNam < m_nPatternNames; pNam++) 114 for (UINT pNam=0; pNam < m_nPatternNames; pNam++)
115 { 115 {
116 if (dwMemPos + 32 >= dwMemLength) return TRUE; 116 if (dwMemPos + 32 >= dwMemLength) return TRUE;
117 tmp = lpStream[dwMemPos++]; 117 tmp = lpStream[dwMemPos++];
118 tmp2 = (tmp < 32) ? tmp : 31; 118 tmp2 = (tmp < 32) ? tmp : 31;
119 if (tmp2) memcpy(m_lpszPatternNames+pNam*32, lpStream+dwMemPos, tmp2); 119 if (tmp2) memcpy(m_lpszPatternNames+pNam*32, lpStream+dwMemPos, tmp2);
120 dwMemPos += tmp; 120 dwMemPos += tmp;
121 } 121 }
122 // Read Song Comments 122 // Read Song Comments
123 tmp = *((WORD *)(lpStream+dwMemPos)); 123 tmp = *((WORD *)(lpStream+dwMemPos));
124 dwMemPos += 2; 124 dwMemPos += 2;
125 if (dwMemPos + tmp >= dwMemLength) return TRUE; 125 if (dwMemPos + tmp >= dwMemLength) return TRUE;
126 if (tmp) 126 if (tmp)
127 { 127 {
128 m_lpszSongComments = new char[tmp+1]; // changed from CHAR 128 m_lpszSongComments = new char[tmp+1]; // changed from CHAR
129 if (!m_lpszSongComments) return TRUE; 129 if (!m_lpszSongComments) return TRUE;
130 memset(m_lpszSongComments, 0, tmp+1); 130 memset(m_lpszSongComments, 0, tmp+1);
131 memcpy(m_lpszSongComments, lpStream + dwMemPos, tmp); 131 memcpy(m_lpszSongComments, lpStream + dwMemPos, tmp);
132 dwMemPos += tmp; 132 dwMemPos += tmp;
133 } 133 }
134 // Read Order List 134 // Read Order List
135 for (UINT iOrd=0; iOrd<pfh->orders; iOrd++, dwMemPos += 2) 135 for (UINT iOrd=0; iOrd<pfh->orders; iOrd++, dwMemPos += 2)
136 { 136 {
137 UINT n = *((WORD *)(lpStream+dwMemPos)); 137 UINT n = *((WORD *)(lpStream+dwMemPos));
138 Order[iOrd] = (BYTE)n; 138 Order[iOrd] = (BYTE)n;
139 } 139 }
140 // Read Patterns 140 // Read Patterns
141 for (UINT iPat=0; iPat<pfh->patterns; iPat++) 141 for (UINT iPat=0; iPat<pfh->patterns; iPat++)
142 { 142 {
143 if (dwMemPos + 4 >= dwMemLength) return TRUE; 143 if (dwMemPos + 4 >= dwMemLength) return TRUE;
144 UINT len = *((DWORD *)(lpStream + dwMemPos)); 144 UINT len = *((DWORD *)(lpStream + dwMemPos));
145 dwMemPos += 4; 145 dwMemPos += 4;
146 if ((len >= dwMemLength) || (dwMemPos + len > dwMemLength)) return TRUE; 146 if ((len >= dwMemLength) || (dwMemPos + len > dwMemLength)) return TRUE;
147 PatternSize[iPat] = 64; 147 PatternSize[iPat] = 64;
148 MODCOMMAND *m = AllocatePattern(PatternSize[iPat], m_nChannels); 148 MODCOMMAND *m = AllocatePattern(PatternSize[iPat], m_nChannels);
149 if (!m) return TRUE; 149 if (!m) return TRUE;
150 Patterns[iPat] = m; 150 Patterns[iPat] = m;
151 const BYTE *p = lpStream + dwMemPos; 151 const BYTE *p = lpStream + dwMemPos;
152 UINT row = 0, i = 0; 152 UINT row = 0, i = 0;
153 while ((row < PatternSize[iPat]) && (i+2 < len)) 153 while ((row < PatternSize[iPat]) && (i+2 < len))
154 { 154 {
155 BYTE b0 = p[i++]; 155 BYTE b0 = p[i++];
156 BYTE b1 = p[i++]; 156 BYTE b1 = p[i++];
157 BYTE b2 = 0; 157 BYTE b2 = 0;
158 UINT ch = b0 & 0x3F; 158 UINT ch = b0 & 0x3F;
159 // Note+Instr 159 // Note+Instr
160 if (!(b0 & 0x40)) 160 if (!(b0 & 0x40))
161 { 161 {
162 b2 = p[i++]; 162 b2 = p[i++];
163 if (ch < m_nChannels) 163 if (ch < m_nChannels)
164 { 164 {
165 if (b1 & 0x7F) m[ch].note = (b1 & 0x7F) + 25; 165 if (b1 & 0x7F) m[ch].note = (b1 & 0x7F) + 25;
166 m[ch].instr = b2; 166 m[ch].instr = b2;
167 } 167 }
168 if (b1 & 0x80) 168 if (b1 & 0x80)
169 { 169 {
170 b0 |= 0x40; 170 b0 |= 0x40;
171 b1 = p[i++]; 171 b1 = p[i++];
172 } 172 }
173 } 173 }
174 // Effect 174 // Effect
175 if (b0 & 0x40) 175 if (b0 & 0x40)
176 { 176 {
177 anothercommand: 177 anothercommand:
178 if (b1 & 0x40) 178 if (b1 & 0x40)
179 { 179 {
180 if (ch < m_nChannels) 180 if (ch < m_nChannels)
181 { 181 {
182 m[ch].volcmd = VOLCMD_VOLUME; 182 m[ch].volcmd = VOLCMD_VOLUME;
183 m[ch].vol = b1 & 0x3F; 183 m[ch].vol = b1 & 0x3F;
184 } 184 }
185 } else 185 } else
186 { 186 {
187 b2 = p[i++]; 187 b2 = p[i++];
188 if (ch < m_nChannels) 188 if (ch < m_nChannels)
189 { 189 {
190 UINT cmd = b1 & 0x3F; 190 UINT cmd = b1 & 0x3F;
191 if (cmd == 0x0C) 191 if (cmd == 0x0C)
192 { 192 {
193 m[ch].volcmd = VOLCMD_VOLUME; 193 m[ch].volcmd = VOLCMD_VOLUME;
194 m[ch].vol = b2 >> 1; 194 m[ch].vol = b2 >> 1;
195 } else 195 } else
196 if (cmd == 0x0E) 196 if (cmd == 0x0E)
197 { 197 {
198 if (!m[ch].command) 198 if (!m[ch].command)
199 { 199 {
200 UINT command = CMD_S3MCMDEX; 200 UINT command = CMD_S3MCMDEX;
201 UINT param = b2; 201 UINT param = b2;
202 switch(param & 0xF0) 202 switch(param & 0xF0)
203 { 203 {
204 case 0x00:if (param & 0x08) { param &= 0x07; param |= 0x90; } else {command=param=0;} break; 204 case 0x00:if (param & 0x08) { param &= 0x07; param |= 0x90; } else {command=param=0;} break;
205 case 0x10:command = CMD_PORTAMENTOUP; param |= 0xF0; break; 205 case 0x10:command = CMD_PORTAMENTOUP; param |= 0xF0; break;
206 case 0x20:command = CMD_PORTAMENTODOWN; param |= 0xF0; break; 206 case 0x20:command = CMD_PORTAMENTODOWN; param |= 0xF0; break;
207 case 0x30:param = (param & 0x0F) | 0x10; break; 207 case 0x30:param = (param & 0x0F) | 0x10; break;
208 case 0x40:param = (param & 0x0F) | 0x30; break; 208 case 0x40:param = (param & 0x0F) | 0x30; break;
209 case 0x50:param = (param & 0x0F) | 0x20; break; 209 case 0x50:param = (param & 0x0F) | 0x20; break;
210 case 0x60:param = (param & 0x0F) | 0xB0; break; 210 case 0x60:param = (param & 0x0F) | 0xB0; break;
211 case 0x70:param = (param & 0x0F) | 0x40; break; 211 case 0x70:param = (param & 0x0F) | 0x40; break;
212 case 0x90:command = CMD_RETRIG; param &= 0x0F; break; 212 case 0x90:command = CMD_RETRIG; param &= 0x0F; break;
213 case 0xA0:if (param & 0x0F) { command = CMD_VOLUMESLIDE; param = (param << 4) | 0x0F; } else command=param=0; break; 213 case 0xA0:if (param & 0x0F) { command = CMD_VOLUMESLIDE; param = (param << 4) | 0x0F; } else command=param=0; break;
214 case 0xB0:if (param & 0x0F) { command = CMD_VOLUMESLIDE; param |= 0xF0; } else command=param=0; break; 214 case 0xB0:if (param & 0x0F) { command = CMD_VOLUMESLIDE; param |= 0xF0; } else command=param=0; break;
215 } 215 }
216 m[ch].command = command; 216 m[ch].command = command;
217 m[ch].param = param; 217 m[ch].param = param;
218 } 218 }
219 } else 219 } else
220 { 220 {
221 m[ch].command = cmd; 221 m[ch].command = cmd;
222 m[ch].param = b2; 222 m[ch].param = b2;
223 ConvertModCommand(&m[ch]); 223 ConvertModCommand(&m[ch]);
224 } 224 }
225 } 225 }
226 } 226 }
227 if (b1 & 0x80) 227 if (b1 & 0x80)
228 { 228 {
229 b1 = p[i++]; 229 b1 = p[i++];
230 if (i <= len) goto anothercommand; 230 if (i <= len) goto anothercommand;
231 } 231 }
232 } 232 }
233 if (b0 & 0x80) 233 if (b0 & 0x80)
234 { 234 {
235 row++; 235 row++;
236 m += m_nChannels; 236 m += m_nChannels;
237 } 237 }
238 } 238 }
239 dwMemPos += len; 239 dwMemPos += len;
240 } 240 }
241 // Read Samples 241 // Read Samples
242 for (UINT iSmp=1; iSmp<=m_nSamples; iSmp++) if (Ins[iSmp].nLength) 242 for (UINT iSmp=1; iSmp<=m_nSamples; iSmp++) if (Ins[iSmp].nLength)
243 { 243 {
244 if (dwMemPos >= dwMemLength - 9) return TRUE; 244 if (dwMemPos >= dwMemLength - 9) return TRUE;
245 UINT flags = (Ins[iSmp].uFlags & CHN_16BIT) ? RS_AMS16 : RS_AMS8; 245 UINT flags = (Ins[iSmp].uFlags & CHN_16BIT) ? RS_AMS16 : RS_AMS8;
246 dwMemPos += ReadSample(&Ins[iSmp], flags, (LPSTR)(lpStream+dwMemPos), dwMemLength-dwMemPos); 246 dwMemPos += ReadSample(&Ins[iSmp], flags, (LPSTR)(lpStream+dwMemPos), dwMemLength-dwMemPos);
247 } 247 }
248 return TRUE; 248 return TRUE;
249} 249}
250 250
251 251
252///////////////////////////////////////////////////////////////////// 252/////////////////////////////////////////////////////////////////////
253// AMS 2.2 loader 253// AMS 2.2 loader
254 254
255#pragma pack(1) 255#pragma pack(1)
256 256
257typedef struct AMS2FILEHEADER 257typedef struct AMS2FILEHEADER
258{ 258{
259 DWORD dwHdr1; // AMShdr 259 DWORD dwHdr1; // AMShdr
260 WORD wHdr2; 260 WORD wHdr2;
261 BYTE b1A; // 0x1A 261 BYTE b1A; // 0x1A
262 BYTE titlelen; // 30-bytes max 262 BYTE titlelen; // 30-bytes max
263 CHAR szTitle[30];// [titlelen] 263 CHAR szTitle[30];// [titlelen]
264} Q_PACKED AMS2FILEHEADER; 264} Q_PACKED AMS2FILEHEADER;
265 265
266typedef struct AMS2SONGHEADER 266typedef struct AMS2SONGHEADER
267{ 267{
268 WORD version; 268 WORD version;
269 BYTE instruments; 269 BYTE instruments;
270 WORD patterns; 270 WORD patterns;
271 WORD orders; 271 WORD orders;
272 WORD bpm; 272 WORD bpm;
273 BYTE speed; 273 BYTE speed;
274 BYTE channels; 274 BYTE channels;
275 BYTE commands; 275 BYTE commands;
276 BYTE rows; 276 BYTE rows;
277 WORD flags; 277 WORD flags;
278} Q_PACKED AMS2SONGHEADER; 278} Q_PACKED AMS2SONGHEADER;
279 279
280typedef struct AMS2INSTRUMENT 280typedef struct AMS2INSTRUMENT
281{ 281{
282 BYTE samples; 282 BYTE samples;
283 BYTE notemap[120]; 283 BYTE notemap[120];
284} Q_PACKED AMS2INSTRUMENT; 284} Q_PACKED AMS2INSTRUMENT;
285 285
286typedef struct AMS2ENVELOPE 286typedef struct AMS2ENVELOPE
287{ 287{
288 BYTE speed; 288 BYTE speed;
289 BYTE sustain; 289 BYTE sustain;
290 BYTE loopbegin; 290 BYTE loopbegin;
291 BYTE loopend; 291 BYTE loopend;
292 BYTE points; 292 BYTE points;
293 BYTE info[3]; 293 BYTE info[3];
294} Q_PACKED AMS2ENVELOPE; 294} Q_PACKED AMS2ENVELOPE;
295 295
296typedef struct AMS2SAMPLE 296typedef struct AMS2SAMPLE
297{ 297{
298 DWORD length; 298 DWORD length;
299 DWORD loopstart; 299 DWORD loopstart;
300 DWORD loopend; 300 DWORD loopend;
301 WORD frequency; 301 WORD frequency;
302 BYTE finetune; 302 BYTE finetune;
303 WORD c4speed; 303 WORD c4speed;
304 CHAR transpose; 304 CHAR transpose;
305 BYTE volume; 305 BYTE volume;
306 BYTE flags; 306 BYTE flags;
307} Q_PACKED AMS2SAMPLE; 307} Q_PACKED AMS2SAMPLE;
308 308
309 309
310#pragma pack() 310#pragma pack()
311 311
312 312
313BOOL CSoundFile::ReadAMS2(LPCBYTE lpStream, DWORD dwMemLength) 313BOOL CSoundFile::ReadAMS2(LPCBYTE lpStream, DWORD dwMemLength)
314//------------------------------------------------------------ 314//------------------------------------------------------------
315{ 315{
316 AMS2FILEHEADER *pfh = (AMS2FILEHEADER *)lpStream; 316 AMS2FILEHEADER *pfh = (AMS2FILEHEADER *)lpStream;
317 AMS2SONGHEADER *psh; 317 AMS2SONGHEADER *psh;
318 DWORD dwMemPos; 318 DWORD dwMemPos;
319 BYTE smpmap[16]; 319 BYTE smpmap[16];
320 BYTE packedsamples[MAX_SAMPLES]; 320 BYTE packedsamples[MAX_SAMPLES];
321 321
322 if ((pfh->dwHdr1 != 0x68534D41) || (pfh->wHdr2 != 0x7264) 322 if ((pfh->dwHdr1 != 0x68534D41) || (pfh->wHdr2 != 0x7264)
323 || (pfh->b1A != 0x1A) || (pfh->titlelen > 30)) return FALSE; 323 || (pfh->b1A != 0x1A) || (pfh->titlelen > 30)) return FALSE;
324 dwMemPos = pfh->titlelen + 8; 324 dwMemPos = pfh->titlelen + 8;
325 psh = (AMS2SONGHEADER *)(lpStream + dwMemPos); 325 psh = (AMS2SONGHEADER *)(lpStream + dwMemPos);
326 if (((psh->version & 0xFF00) != 0x0200) || (!psh->instruments) 326 if (((psh->version & 0xFF00) != 0x0200) || (!psh->instruments)
327 || (psh->instruments > MAX_INSTRUMENTS) || (!psh->patterns) || (!psh->orders)) return FALSE; 327 || (psh->instruments > MAX_INSTRUMENTS) || (!psh->patterns) || (!psh->orders)) return FALSE;
328 dwMemPos += sizeof(AMS2SONGHEADER); 328 dwMemPos += sizeof(AMS2SONGHEADER);
329 if (pfh->titlelen) 329 if (pfh->titlelen)
330 { 330 {
331 memcpy(m_szNames, pfh->szTitle, pfh->titlelen); 331 memcpy(m_szNames, pfh->szTitle, pfh->titlelen);
332 m_szNames[0][pfh->titlelen] = 0; 332 m_szNames[0][pfh->titlelen] = 0;
333 } 333 }
334 m_nType = MOD_TYPE_AMS; 334 m_nType = MOD_TYPE_AMS;
335 m_nChannels = 32; 335 m_nChannels = 32;
336 m_nDefaultTempo = psh->bpm >> 8; 336 m_nDefaultTempo = psh->bpm >> 8;
337 m_nDefaultSpeed = psh->speed; 337 m_nDefaultSpeed = psh->speed;
338 m_nInstruments = psh->instruments; 338 m_nInstruments = psh->instruments;
339 m_nSamples = 0; 339 m_nSamples = 0;
340 if (psh->flags & 0x40) m_dwSongFlags |= SONG_LINEARSLIDES; 340 if (psh->flags & 0x40) m_dwSongFlags |= SONG_LINEARSLIDES;
341 for (UINT nIns=1; nIns<=m_nInstruments; nIns++) 341 for (UINT nIns=1; nIns<=m_nInstruments; nIns++)
342 { 342 {
343 UINT insnamelen = lpStream[dwMemPos]; 343 UINT insnamelen = lpStream[dwMemPos];
344 CHAR *pinsname = (CHAR *)(lpStream+dwMemPos+1); 344 CHAR *pinsname = (CHAR *)(lpStream+dwMemPos+1);
345 dwMemPos += insnamelen + 1; 345 dwMemPos += insnamelen + 1;
346 AMS2INSTRUMENT *pins = (AMS2INSTRUMENT *)(lpStream + dwMemPos); 346 AMS2INSTRUMENT *pins = (AMS2INSTRUMENT *)(lpStream + dwMemPos);
347 dwMemPos += sizeof(AMS2INSTRUMENT); 347 dwMemPos += sizeof(AMS2INSTRUMENT);
348 if (dwMemPos + 1024 >= dwMemLength) return TRUE; 348 if (dwMemPos + 1024 >= dwMemLength) return TRUE;
349 AMS2ENVELOPE *volenv, *panenv, *pitchenv; 349 AMS2ENVELOPE *volenv, *panenv, *pitchenv;
350 volenv = (AMS2ENVELOPE *)(lpStream+dwMemPos); 350 volenv = (AMS2ENVELOPE *)(lpStream+dwMemPos);
351 dwMemPos += 5 + volenv->points*3; 351 dwMemPos += 5 + volenv->points*3;
352 panenv = (AMS2ENVELOPE *)(lpStream+dwMemPos); 352 panenv = (AMS2ENVELOPE *)(lpStream+dwMemPos);
353 dwMemPos += 5 + panenv->points*3; 353 dwMemPos += 5 + panenv->points*3;
354 pitchenv = (AMS2ENVELOPE *)(lpStream+dwMemPos); 354 pitchenv = (AMS2ENVELOPE *)(lpStream+dwMemPos);
355 dwMemPos += 5 + pitchenv->points*3; 355 dwMemPos += 5 + pitchenv->points*3;
356 INSTRUMENTHEADER *penv = new INSTRUMENTHEADER; 356 INSTRUMENTHEADER *penv = new INSTRUMENTHEADER;
357 if (!penv) return TRUE; 357 if (!penv) return TRUE;
358 memset(smpmap, 0, sizeof(smpmap)); 358 memset(smpmap, 0, sizeof(smpmap));
359 memset(penv, 0, sizeof(INSTRUMENTHEADER)); 359 memset(penv, 0, sizeof(INSTRUMENTHEADER));
360 for (UINT ismpmap=0; ismpmap<pins->samples; ismpmap++) 360 for (UINT ismpmap=0; ismpmap<pins->samples; ismpmap++)
361 { 361 {
362 if ((ismpmap >= 16) || (m_nSamples+1 >= MAX_SAMPLES)) break; 362 if ((ismpmap >= 16) || (m_nSamples+1 >= MAX_SAMPLES)) break;
363 m_nSamples++; 363 m_nSamples++;
364 smpmap[ismpmap] = m_nSamples; 364 smpmap[ismpmap] = m_nSamples;
365 } 365 }
366 penv->nGlobalVol = 64; 366 penv->nGlobalVol = 64;
367 penv->nPan = 128; 367 penv->nPan = 128;
368 penv->nPPC = 60; 368 penv->nPPC = 60;
369 Headers[nIns] = penv; 369 Headers[nIns] = penv;
370 if (insnamelen) 370 if (insnamelen)
371 { 371 {
372 if (insnamelen > 31) insnamelen = 31; 372 if (insnamelen > 31) insnamelen = 31;
373 memcpy(penv->name, pinsname, insnamelen); 373 memcpy(penv->name, pinsname, insnamelen);
374 penv->name[insnamelen] = 0; 374 penv->name[insnamelen] = 0;
375 } 375 }
376 for (UINT inotemap=0; inotemap<120; inotemap++) 376 for (UINT inotemap=0; inotemap<120; inotemap++)
377 { 377 {
378 penv->NoteMap[inotemap] = inotemap+1; 378 penv->NoteMap[inotemap] = inotemap+1;
379 penv->Keyboard[inotemap] = smpmap[pins->notemap[inotemap] & 0x0F]; 379 penv->Keyboard[inotemap] = smpmap[pins->notemap[inotemap] & 0x0F];
380 } 380 }
381 // Volume Envelope 381 // Volume Envelope
382 { 382 {
383 UINT pos = 0; 383 UINT pos = 0;
384 penv->nVolEnv = (volenv->points > 16) ? 16 : volenv->points; 384 penv->nVolEnv = (volenv->points > 16) ? 16 : volenv->points;
385 penv->nVolSustainBegin = penv->nVolSustainEnd = volenv->sustain; 385 penv->nVolSustainBegin = penv->nVolSustainEnd = volenv->sustain;
386 penv->nVolLoopStart = volenv->loopbegin; 386 penv->nVolLoopStart = volenv->loopbegin;
387 penv->nVolLoopEnd = volenv->loopend; 387 penv->nVolLoopEnd = volenv->loopend;
388 for (UINT i=0; i<penv->nVolEnv; i++) 388 for (UINT i=0; i<penv->nVolEnv; i++)
389 { 389 {
390 penv->VolEnv[i] = (BYTE)((volenv->info[i*3+2] & 0x7F) >> 1); 390 penv->VolEnv[i] = (BYTE)((volenv->info[i*3+2] & 0x7F) >> 1);
391 pos += volenv->info[i*3] + ((volenv->info[i*3+1] & 1) << 8); 391 pos += volenv->info[i*3] + ((volenv->info[i*3+1] & 1) << 8);
392 penv->VolPoints[i] = (WORD)pos; 392 penv->VolPoints[i] = (WORD)pos;
393 } 393 }
394 } 394 }
395 penv->nFadeOut = (((lpStream[dwMemPos+2] & 0x0F) << 8) | (lpStream[dwMemPos+1])) << 3; 395 penv->nFadeOut = (((lpStream[dwMemPos+2] & 0x0F) << 8) | (lpStream[dwMemPos+1])) << 3;
396 UINT envflags = lpStream[dwMemPos+3]; 396 UINT envflags = lpStream[dwMemPos+3];
397 if (envflags & 0x01) penv->dwFlags |= ENV_VOLLOOP; 397 if (envflags & 0x01) penv->dwFlags |= ENV_VOLLOOP;
398 if (envflags & 0x02) penv->dwFlags |= ENV_VOLSUSTAIN; 398 if (envflags & 0x02) penv->dwFlags |= ENV_VOLSUSTAIN;
399 if (envflags & 0x04) penv->dwFlags |= ENV_VOLUME; 399 if (envflags & 0x04) penv->dwFlags |= ENV_VOLUME;
400 dwMemPos += 5; 400 dwMemPos += 5;
401 // Read Samples 401 // Read Samples
402 for (UINT ismp=0; ismp<pins->samples; ismp++) 402 for (UINT ismp=0; ismp<pins->samples; ismp++)
403 { 403 {
404 MODINSTRUMENT *psmp = ((ismp < 16) && (smpmap[ismp])) ? &Ins[smpmap[ismp]] : NULL; 404 MODINSTRUMENT *psmp = ((ismp < 16) && (smpmap[ismp])) ? &Ins[smpmap[ismp]] : NULL;
405 UINT smpnamelen = lpStream[dwMemPos]; 405 UINT smpnamelen = lpStream[dwMemPos];
406 if ((psmp) && (smpnamelen) && (smpnamelen <= 22)) 406 if ((psmp) && (smpnamelen) && (smpnamelen <= 22))
407 { 407 {
408 memcpy(m_szNames[smpmap[ismp]], lpStream+dwMemPos+1, smpnamelen); 408 memcpy(m_szNames[smpmap[ismp]], lpStream+dwMemPos+1, smpnamelen);
409 } 409 }
410 dwMemPos += smpnamelen + 1; 410 dwMemPos += smpnamelen + 1;
411 if (psmp) 411 if (psmp)
412 { 412 {
413 AMS2SAMPLE *pams = (AMS2SAMPLE *)(lpStream+dwMemPos); 413 AMS2SAMPLE *pams = (AMS2SAMPLE *)(lpStream+dwMemPos);
414 psmp->nGlobalVol = 64; 414 psmp->nGlobalVol = 64;
415 psmp->nPan = 128; 415 psmp->nPan = 128;
416 psmp->nLength = pams->length; 416 psmp->nLength = pams->length;
417 psmp->nLoopStart = pams->loopstart; 417 psmp->nLoopStart = pams->loopstart;
418 psmp->nLoopEnd = pams->loopend; 418 psmp->nLoopEnd = pams->loopend;
419 psmp->nC4Speed = pams->c4speed; 419 psmp->nC4Speed = pams->c4speed;
420 psmp->RelativeTone = pams->transpose; 420 psmp->RelativeTone = pams->transpose;
421 psmp->nVolume = pams->volume / 2; 421 psmp->nVolume = pams->volume / 2;
422 packedsamples[smpmap[ismp]] = pams->flags; 422 packedsamples[smpmap[ismp]] = pams->flags;
423 if (pams->flags & 0x04) psmp->uFlags |= CHN_16BIT; 423 if (pams->flags & 0x04) psmp->uFlags |= CHN_16BIT;
424 if (pams->flags & 0x08) psmp->uFlags |= CHN_LOOP; 424 if (pams->flags & 0x08) psmp->uFlags |= CHN_LOOP;
425 if (pams->flags & 0x10) psmp->uFlags |= CHN_PINGPONGLOOP; 425 if (pams->flags & 0x10) psmp->uFlags |= CHN_PINGPONGLOOP;
426 } 426 }
427 dwMemPos += sizeof(AMS2SAMPLE); 427 dwMemPos += sizeof(AMS2SAMPLE);
428 } 428 }
429 } 429 }
430 if (dwMemPos + 256 >= dwMemLength) return TRUE; 430 if (dwMemPos + 256 >= dwMemLength) return TRUE;
431 // Comments 431 // Comments
432 { 432 {
433 UINT composernamelen = lpStream[dwMemPos]; 433 UINT composernamelen = lpStream[dwMemPos];
434 if (composernamelen) 434 if (composernamelen)
435 { 435 {
436 m_lpszSongComments = new char[composernamelen+1]; // changed from CHAR 436 m_lpszSongComments = new char[composernamelen+1]; // changed from CHAR
437 if (m_lpszSongComments) 437 if (m_lpszSongComments)
438 { 438 {
439 memcpy(m_lpszSongComments, lpStream+dwMemPos+1, composernamelen); 439 memcpy(m_lpszSongComments, lpStream+dwMemPos+1, composernamelen);
440 m_lpszSongComments[composernamelen] = 0; 440 m_lpszSongComments[composernamelen] = 0;
441 } 441 }
442 } 442 }
443 dwMemPos += composernamelen + 1; 443 dwMemPos += composernamelen + 1;
444 // channel names 444 // channel names
445 for (UINT i=0; i<32; i++) 445 for (UINT i=0; i<32; i++)
446 { 446 {
447 UINT chnnamlen = lpStream[dwMemPos]; 447 UINT chnnamlen = lpStream[dwMemPos];
448 if ((chnnamlen) && (chnnamlen < MAX_CHANNELNAME)) 448 if ((chnnamlen) && (chnnamlen < MAX_CHANNELNAME))
449 { 449 {
450 memcpy(ChnSettings[i].szName, lpStream+dwMemPos+1, chnnamlen); 450 memcpy(ChnSettings[i].szName, lpStream+dwMemPos+1, chnnamlen);
451 } 451 }
452 dwMemPos += chnnamlen + 1; 452 dwMemPos += chnnamlen + 1;
453 if (dwMemPos + chnnamlen + 256 >= dwMemLength) return TRUE; 453 if (dwMemPos + chnnamlen + 256 >= dwMemLength) return TRUE;
454 } 454 }
455 // packed comments (ignored) 455 // packed comments (ignored)
456 UINT songtextlen = *((LPDWORD)(lpStream+dwMemPos)); 456 UINT songtextlen = *((LPDWORD)(lpStream+dwMemPos));
457 dwMemPos += songtextlen; 457 dwMemPos += songtextlen;
458 if (dwMemPos + 256 >= dwMemLength) return TRUE; 458 if (dwMemPos + 256 >= dwMemLength) return TRUE;
459 } 459 }
460 // Order List 460 // Order List
461 { 461 {
462 for (UINT i=0; i<MAX_ORDERS; i++) 462 for (UINT i=0; i<MAX_ORDERS; i++)
463 { 463 {
464 Order[i] = 0xFF; 464 Order[i] = 0xFF;
465 if (dwMemPos + 2 >= dwMemLength) return TRUE; 465 if (dwMemPos + 2 >= dwMemLength) return TRUE;
466 if (i < psh->orders) 466 if (i < psh->orders)
467 { 467 {
468 Order[i] = lpStream[dwMemPos]; 468 Order[i] = lpStream[dwMemPos];
469 dwMemPos += 2; 469 dwMemPos += 2;
470 } 470 }
471 } 471 }
472 } 472 }
473 // Pattern Data 473 // Pattern Data
474 for (UINT ipat=0; ipat<psh->patterns; ipat++) 474 for (UINT ipat=0; ipat<psh->patterns; ipat++)
475 { 475 {
476 if (dwMemPos+8 >= dwMemLength) return TRUE; 476 if (dwMemPos+8 >= dwMemLength) return TRUE;
477 UINT packedlen = *((LPDWORD)(lpStream+dwMemPos)); 477 UINT packedlen = *((LPDWORD)(lpStream+dwMemPos));
478 UINT numrows = 1 + (UINT)(lpStream[dwMemPos+4]); 478 UINT numrows = 1 + (UINT)(lpStream[dwMemPos+4]);
479 //UINT patchn = 1 + (UINT)(lpStream[dwMemPos+5] & 0x1F); 479 //UINT patchn = 1 + (UINT)(lpStream[dwMemPos+5] & 0x1F);
480 //UINT patcmds = 1 + (UINT)(lpStream[dwMemPos+5] >> 5); 480 //UINT patcmds = 1 + (UINT)(lpStream[dwMemPos+5] >> 5);
481 UINT patnamlen = lpStream[dwMemPos+6]; 481 UINT patnamlen = lpStream[dwMemPos+6];
482 dwMemPos += 4; 482 dwMemPos += 4;
483 if ((ipat < MAX_PATTERNS) && (packedlen < dwMemLength-dwMemPos) && (numrows >= 8)) 483 if ((ipat < MAX_PATTERNS) && (packedlen < dwMemLength-dwMemPos) && (numrows >= 8))
484 { 484 {
485 if ((patnamlen) && (patnamlen < MAX_PATTERNNAME)) 485 if ((patnamlen) && (patnamlen < MAX_PATTERNNAME))
486 { 486 {
487 char s[MAX_PATTERNNAME]; // changed from CHAR 487 char s[MAX_PATTERNNAME]; // changed from CHAR
488 memcpy(s, lpStream+dwMemPos+3, patnamlen); 488 memcpy(s, lpStream+dwMemPos+3, patnamlen);
489 s[patnamlen] = 0; 489 s[patnamlen] = 0;
490 SetPatternName(ipat, s); 490 SetPatternName(ipat, s);
491 } 491 }
492 PatternSize[ipat] = numrows; 492 PatternSize[ipat] = numrows;
493 Patterns[ipat] = AllocatePattern(numrows, m_nChannels); 493 Patterns[ipat] = AllocatePattern(numrows, m_nChannels);
494 if (!Patterns[ipat]) return TRUE; 494 if (!Patterns[ipat]) return TRUE;
495 // Unpack Pattern Data 495 // Unpack Pattern Data
496 LPCBYTE psrc = lpStream + dwMemPos; 496 LPCBYTE psrc = lpStream + dwMemPos;
497 UINT pos = 3 + patnamlen; 497 UINT pos = 3 + patnamlen;
498 UINT row = 0; 498 UINT row = 0;
499 while ((pos < packedlen) && (row < numrows)) 499 while ((pos < packedlen) && (row < numrows))
500 { 500 {
501 MODCOMMAND *m = Patterns[ipat] + row * m_nChannels; 501 MODCOMMAND *m = Patterns[ipat] + row * m_nChannels;
502 UINT byte1 = psrc[pos++]; 502 UINT byte1 = psrc[pos++];
503 UINT ch = byte1 & 0x1F; 503 UINT ch = byte1 & 0x1F;
504 // Read Note + Instr 504 // Read Note + Instr
505 if (!(byte1 & 0x40)) 505 if (!(byte1 & 0x40))
506 { 506 {
507 UINT byte2 = psrc[pos++]; 507 UINT byte2 = psrc[pos++];
508 UINT note = byte2 & 0x7F; 508 UINT note = byte2 & 0x7F;
509 if (note) m[ch].note = (note > 1) ? (note-1) : 0xFF; 509 if (note) m[ch].note = (note > 1) ? (note-1) : 0xFF;
510 m[ch].instr = psrc[pos++]; 510 m[ch].instr = psrc[pos++];
511 // Read Effect 511 // Read Effect
512 while (byte2 & 0x80) 512 while (byte2 & 0x80)
513 { 513 {
514 byte2 = psrc[pos++]; 514 byte2 = psrc[pos++];
515 if (byte2 & 0x40) 515 if (byte2 & 0x40)
516 { 516 {
517 m[ch].volcmd = VOLCMD_VOLUME; 517 m[ch].volcmd = VOLCMD_VOLUME;
518 m[ch].vol = byte2 & 0x3F; 518 m[ch].vol = byte2 & 0x3F;
519 } else 519 } else
520 { 520 {
521 UINT command = byte2 & 0x3F; 521 UINT command = byte2 & 0x3F;
522 UINT param = psrc[pos++]; 522 UINT param = psrc[pos++];
523 if (command == 0x0C) 523 if (command == 0x0C)
524 { 524 {
525 m[ch].volcmd = VOLCMD_VOLUME; 525 m[ch].volcmd = VOLCMD_VOLUME;
526 m[ch].vol = param / 2; 526 m[ch].vol = param / 2;
527 } else 527 } else
528 if (command < 0x10) 528 if (command < 0x10)
529 { 529 {
530 m[ch].command = command; 530 m[ch].command = command;
531 m[ch].param = param; 531 m[ch].param = param;
532 ConvertModCommand(&m[ch]); 532 ConvertModCommand(&m[ch]);
533 } else 533 } else
534 { 534 {
535 // TODO: AMS effects 535 // TODO: AMS effects
536 } 536 }
537 } 537 }
538 } 538 }
539 } 539 }
540 if (byte1 & 0x80) row++; 540 if (byte1 & 0x80) row++;
541 } 541 }
542 } 542 }
543 dwMemPos += packedlen; 543 dwMemPos += packedlen;
544 } 544 }
545 // Read Samples 545 // Read Samples
546 for (UINT iSmp=1; iSmp<=m_nSamples; iSmp++) if (Ins[iSmp].nLength) 546 for (UINT iSmp=1; iSmp<=m_nSamples; iSmp++) if (Ins[iSmp].nLength)
547 { 547 {
548 if (dwMemPos >= dwMemLength - 9) return TRUE; 548 if (dwMemPos >= dwMemLength - 9) return TRUE;
549 UINT flags; 549 UINT flags;
550 if (packedsamples[iSmp] & 0x03) 550 if (packedsamples[iSmp] & 0x03)
551 { 551 {
552 flags = (Ins[iSmp].uFlags & CHN_16BIT) ? RS_AMS16 : RS_AMS8; 552 flags = (Ins[iSmp].uFlags & CHN_16BIT) ? RS_AMS16 : RS_AMS8;
553 } else 553 } else
554 { 554 {
555 flags = (Ins[iSmp].uFlags & CHN_16BIT) ? RS_PCM16S : RS_PCM8S; 555 flags = (Ins[iSmp].uFlags & CHN_16BIT) ? RS_PCM16S : RS_PCM8S;
556 } 556 }
557 dwMemPos += ReadSample(&Ins[iSmp], flags, (LPSTR)(lpStream+dwMemPos), dwMemLength-dwMemPos); 557 dwMemPos += ReadSample(&Ins[iSmp], flags, (LPSTR)(lpStream+dwMemPos), dwMemLength-dwMemPos);
558 } 558 }
559 return TRUE; 559 return TRUE;
560} 560}
561 561
562 562
563///////////////////////////////////////////////////////////////////// 563/////////////////////////////////////////////////////////////////////
564// AMS Sample unpacking 564// AMS Sample unpacking
565 565
566void AMSUnpack(const char *psrc, UINT inputlen, char *pdest, UINT dmax, char packcharacter) 566void AMSUnpack(const char *psrc, UINT inputlen, char *pdest, UINT dmax, char packcharacter)
567{ 567{
568 UINT tmplen = dmax; 568 UINT tmplen = dmax;
569 signed char *amstmp = new signed char[tmplen]; 569 signed char *amstmp = new signed char[tmplen];
570 570
571 if (!amstmp) return; 571 if (!amstmp) return;
572 // Unpack Loop 572 // Unpack Loop
573 { 573 {
574 signed char *p = amstmp; 574 signed char *p = amstmp;
575 UINT i=0, j=0; 575 UINT i=0, j=0;
576 while ((i < inputlen) && (j < tmplen)) 576 while ((i < inputlen) && (j < tmplen))
577 { 577 {
578 signed char ch = psrc[i++]; 578 signed char ch = psrc[i++];
579 if (ch == packcharacter) 579 if (ch == packcharacter)
580 { 580 {
581 BYTE ch2 = psrc[i++]; 581 BYTE ch2 = psrc[i++];
582 if (ch2) 582 if (ch2)
583 { 583 {
584 ch = psrc[i++]; 584 ch = psrc[i++];
585 while (ch2--) 585 while (ch2--)
586 { 586 {
587 p[j++] = ch; 587 p[j++] = ch;
588 if (j >= tmplen) break; 588 if (j >= tmplen) break;
589 } 589 }
590 } else p[j++] = packcharacter; 590 } else p[j++] = packcharacter;
591 } else p[j++] = ch; 591 } else p[j++] = ch;
592 } 592 }
593 } 593 }
594 // Bit Unpack Loop 594 // Bit Unpack Loop
595 { 595 {
596 signed char *p = amstmp; 596 signed char *p = amstmp;
597 UINT bitcount = 0x80, dh; 597 UINT bitcount = 0x80, dh;
598 UINT k=0; 598 UINT k=0;
599 for (UINT i=0; i<dmax; i++) 599 for (UINT i=0; i<dmax; i++)
600 { 600 {
601 BYTE al = *p++; 601 BYTE al = *p++;
602 dh = 0; 602 dh = 0;
603 for (UINT count=0; count<8; count++) 603 for (UINT count=0; count<8; count++)
604 { 604 {
605 UINT bl = al & bitcount; 605 UINT bl = al & bitcount;
606 bl = ((bl|(bl<<8)) >> ((dh+8-count) & 7)) & 0xFF; 606 bl = ((bl|(bl<<8)) >> ((dh+8-count) & 7)) & 0xFF;
607 bitcount = ((bitcount|(bitcount<<8)) >> 1) & 0xFF; 607 bitcount = ((bitcount|(bitcount<<8)) >> 1) & 0xFF;
608 pdest[k++] |= bl; 608 pdest[k++] |= bl;
609 if (k >= dmax) 609 if (k >= dmax)
610 { 610 {
611 k = 0; 611 k = 0;
612 dh++; 612 dh++;
613 } 613 }
614 } 614 }
615 bitcount = ((bitcount|(bitcount<<8)) >> dh) & 0xFF; 615 bitcount = ((bitcount|(bitcount<<8)) >> dh) & 0xFF;
616 } 616 }
617 } 617 }
618 // Delta Unpack 618 // Delta Unpack
619 { 619 {
620 signed char old = 0; 620 signed char old = 0;
621 for (UINT i=0; i<dmax; i++) 621 for (UINT i=0; i<dmax; i++)
622 { 622 {
623 int pos = ((LPBYTE)pdest)[i]; 623 int pos = ((LPBYTE)pdest)[i];
624 if ((pos != 128) && (pos & 0x80)) pos = -(pos & 0x7F); 624 if ((pos != 128) && (pos & 0x80)) pos = -(pos & 0x7F);
625 old -= (signed char)pos; 625 old -= (signed char)pos;
626 pdest[i] = old; 626 pdest[i] = old;
627 } 627 }
628 } 628 }
629 delete amstmp; 629 delete [] amstmp;
630} 630}
631 631
diff --git a/core/multimedia/opieplayer/modplug/load_mdl.cpp b/core/multimedia/opieplayer/modplug/load_mdl.cpp
index 806b68b..e1f78d5 100644
--- a/core/multimedia/opieplayer/modplug/load_mdl.cpp
+++ b/core/multimedia/opieplayer/modplug/load_mdl.cpp
@@ -1,506 +1,506 @@
1/* 1/*
2 * This program is free software; you can redistribute it and modify it 2 * This program is free software; you can redistribute it and modify it
3 * under the terms of the GNU General Public License as published by the 3 * under the terms of the GNU General Public License as published by the
4 * Free Software Foundation; either version 2 of the license or (at your 4 * Free Software Foundation; either version 2 of the license or (at your
5 * option) any later version. 5 * option) any later version.
6 * 6 *
7 * Authors: Olivier Lapicque <olivierl@jps.net> 7 * Authors: Olivier Lapicque <olivierl@jps.net>
8*/ 8*/
9 9
10////////////////////////////////////////////// 10//////////////////////////////////////////////
11// DigiTracker (MDL) module loader // 11// DigiTracker (MDL) module loader //
12////////////////////////////////////////////// 12//////////////////////////////////////////////
13#include "stdafx.h" 13#include "stdafx.h"
14#include "sndfile.h" 14#include "sndfile.h"
15 15
16//#pragma warning(disable:4244) 16//#pragma warning(disable:4244)
17 17
18typedef struct MDLSONGHEADER 18typedef struct MDLSONGHEADER
19{ 19{
20 DWORD id;// "DMDL" = 0x4C444D44 20 DWORD id;// "DMDL" = 0x4C444D44
21 BYTE version; 21 BYTE version;
22} Q_PACKED MDLSONGHEADER; 22} Q_PACKED MDLSONGHEADER;
23 23
24 24
25typedef struct MDLINFOBLOCK 25typedef struct MDLINFOBLOCK
26{ 26{
27 CHAR songname[32]; 27 CHAR songname[32];
28 CHAR composer[20]; 28 CHAR composer[20];
29 WORD norders; 29 WORD norders;
30 WORD repeatpos; 30 WORD repeatpos;
31 BYTE globalvol; 31 BYTE globalvol;
32 BYTE speed; 32 BYTE speed;
33 BYTE tempo; 33 BYTE tempo;
34 BYTE channelinfo[32]; 34 BYTE channelinfo[32];
35 BYTE seq[256]; 35 BYTE seq[256];
36} Q_PACKED MDLINFOBLOCK; 36} Q_PACKED MDLINFOBLOCK;
37 37
38 38
39typedef struct MDLPATTERNDATA 39typedef struct MDLPATTERNDATA
40{ 40{
41 BYTE channels; 41 BYTE channels;
42 BYTE lastrow;// nrows = lastrow+1 42 BYTE lastrow;// nrows = lastrow+1
43 CHAR name[16]; 43 CHAR name[16];
44 WORD data[1]; 44 WORD data[1];
45} Q_PACKED MDLPATTERNDATA; 45} Q_PACKED MDLPATTERNDATA;
46 46
47 47
48void ConvertMDLCommand(MODCOMMAND *m, UINT eff, UINT data) 48void ConvertMDLCommand(MODCOMMAND *m, UINT eff, UINT data)
49//-------------------------------------------------------- 49//--------------------------------------------------------
50{ 50{
51 UINT command = 0, param = data; 51 UINT command = 0, param = data;
52 switch(eff) 52 switch(eff)
53 { 53 {
54 case 0x01:command = CMD_PORTAMENTOUP; break; 54 case 0x01:command = CMD_PORTAMENTOUP; break;
55 case 0x02:command = CMD_PORTAMENTODOWN; break; 55 case 0x02:command = CMD_PORTAMENTODOWN; break;
56 case 0x03:command = CMD_TONEPORTAMENTO; break; 56 case 0x03:command = CMD_TONEPORTAMENTO; break;
57 case 0x04:command = CMD_VIBRATO; break; 57 case 0x04:command = CMD_VIBRATO; break;
58 case 0x05:command = CMD_ARPEGGIO; break; 58 case 0x05:command = CMD_ARPEGGIO; break;
59 case 0x07:command = (param < 0x20) ? CMD_SPEED : CMD_TEMPO; break; 59 case 0x07:command = (param < 0x20) ? CMD_SPEED : CMD_TEMPO; break;
60 case 0x08:command = CMD_PANNING8; param <<= 1; break; 60 case 0x08:command = CMD_PANNING8; param <<= 1; break;
61 case 0x0B:command = CMD_POSITIONJUMP; break; 61 case 0x0B:command = CMD_POSITIONJUMP; break;
62 case 0x0C:command = CMD_GLOBALVOLUME; break; 62 case 0x0C:command = CMD_GLOBALVOLUME; break;
63 case 0x0D:command = CMD_PATTERNBREAK; param = (data & 0x0F) + (data>>4)*10; break; 63 case 0x0D:command = CMD_PATTERNBREAK; param = (data & 0x0F) + (data>>4)*10; break;
64 case 0x0E: 64 case 0x0E:
65 command = CMD_S3MCMDEX; 65 command = CMD_S3MCMDEX;
66 switch(data & 0xF0) 66 switch(data & 0xF0)
67 { 67 {
68 case 0x00:command = 0; break; // What is E0x in MDL (there is a bunch) ? 68 case 0x00:command = 0; break; // What is E0x in MDL (there is a bunch) ?
69 case 0x10:if (param & 0x0F) { param |= 0xF0; command = CMD_PANNINGSLIDE; } else command = 0; break; 69 case 0x10:if (param & 0x0F) { param |= 0xF0; command = CMD_PANNINGSLIDE; } else command = 0; break;
70 case 0x20:if (param & 0x0F) { param = (param << 4) | 0x0F; command = CMD_PANNINGSLIDE; } else command = 0; break; 70 case 0x20:if (param & 0x0F) { param = (param << 4) | 0x0F; command = CMD_PANNINGSLIDE; } else command = 0; break;
71 case 0x30:param = (data & 0x0F) | 0x10; break; // glissando 71 case 0x30:param = (data & 0x0F) | 0x10; break; // glissando
72 case 0x40:param = (data & 0x0F) | 0x30; break; // vibrato waveform 72 case 0x40:param = (data & 0x0F) | 0x30; break; // vibrato waveform
73 case 0x60:param = (data & 0x0F) | 0xB0; break; 73 case 0x60:param = (data & 0x0F) | 0xB0; break;
74 case 0x70:param = (data & 0x0F) | 0x40; break; // tremolo waveform 74 case 0x70:param = (data & 0x0F) | 0x40; break; // tremolo waveform
75 case 0x90:command = CMD_RETRIG; param &= 0x0F; break; 75 case 0x90:command = CMD_RETRIG; param &= 0x0F; break;
76 case 0xA0:param = (data & 0x0F) << 4; command = CMD_GLOBALVOLSLIDE; break; 76 case 0xA0:param = (data & 0x0F) << 4; command = CMD_GLOBALVOLSLIDE; break;
77 case 0xB0:param = data & 0x0F; command = CMD_GLOBALVOLSLIDE; break; 77 case 0xB0:param = data & 0x0F; command = CMD_GLOBALVOLSLIDE; break;
78 case 0xF0:param = ((data >> 8) & 0x0F) | 0xA0; break; 78 case 0xF0:param = ((data >> 8) & 0x0F) | 0xA0; break;
79 } 79 }
80 break; 80 break;
81 case 0x0F:command = CMD_SPEED; break; 81 case 0x0F:command = CMD_SPEED; break;
82 case 0x10:if ((param & 0xF0) != 0xE0) { command = CMD_VOLUMESLIDE; if ((param & 0xF0) == 0xF0) param = ((param << 4) | 0x0F); else param >>= 2; } break; 82 case 0x10:if ((param & 0xF0) != 0xE0) { command = CMD_VOLUMESLIDE; if ((param & 0xF0) == 0xF0) param = ((param << 4) | 0x0F); else param >>= 2; } break;
83 case 0x20:if ((param & 0xF0) != 0xE0) { command = CMD_VOLUMESLIDE; if ((param & 0xF0) != 0xF0) param >>= 2; } break; 83 case 0x20:if ((param & 0xF0) != 0xE0) { command = CMD_VOLUMESLIDE; if ((param & 0xF0) != 0xF0) param >>= 2; } break;
84 case 0x30:command = CMD_RETRIG; break; 84 case 0x30:command = CMD_RETRIG; break;
85 case 0x40:command = CMD_TREMOLO; break; 85 case 0x40:command = CMD_TREMOLO; break;
86 case 0x50:command = CMD_TREMOR; break; 86 case 0x50:command = CMD_TREMOR; break;
87 case 0xEF:if (param > 0xFF) param = 0xFF; command = CMD_OFFSET; break; 87 case 0xEF:if (param > 0xFF) param = 0xFF; command = CMD_OFFSET; break;
88 } 88 }
89 if (command) 89 if (command)
90 { 90 {
91 m->command = command; 91 m->command = command;
92 m->param = param; 92 m->param = param;
93 } 93 }
94} 94}
95 95
96 96
97void UnpackMDLTrack(MODCOMMAND *pat, UINT nChannels, UINT nRows, UINT nTrack, const BYTE *lpTracks) 97void UnpackMDLTrack(MODCOMMAND *pat, UINT nChannels, UINT nRows, UINT nTrack, const BYTE *lpTracks)
98//------------------------------------------------------------------------------------------------- 98//-------------------------------------------------------------------------------------------------
99{ 99{
100 MODCOMMAND cmd, *m = pat; 100 MODCOMMAND cmd, *m = pat;
101 UINT len = *((WORD *)lpTracks); 101 UINT len = *((WORD *)lpTracks);
102 UINT pos = 0, row = 0, i; 102 UINT pos = 0, row = 0, i;
103 lpTracks += 2; 103 lpTracks += 2;
104 for (UINT ntrk=1; ntrk<nTrack; ntrk++) 104 for (UINT ntrk=1; ntrk<nTrack; ntrk++)
105 { 105 {
106 lpTracks += len; 106 lpTracks += len;
107 len = *((WORD *)lpTracks); 107 len = *((WORD *)lpTracks);
108 lpTracks += 2; 108 lpTracks += 2;
109 } 109 }
110 cmd.note = cmd.instr = 0; 110 cmd.note = cmd.instr = 0;
111 cmd.volcmd = cmd.vol = 0; 111 cmd.volcmd = cmd.vol = 0;
112 cmd.command = cmd.param = 0; 112 cmd.command = cmd.param = 0;
113 while ((row < nRows) && (pos < len)) 113 while ((row < nRows) && (pos < len))
114 { 114 {
115 UINT xx; 115 UINT xx;
116 BYTE b = lpTracks[pos++]; 116 BYTE b = lpTracks[pos++];
117 xx = b >> 2; 117 xx = b >> 2;
118 switch(b & 0x03) 118 switch(b & 0x03)
119 { 119 {
120 case 0x01: 120 case 0x01:
121 for (i=0; i<=xx; i++) 121 for (i=0; i<=xx; i++)
122 { 122 {
123 if (row) *m = *(m-nChannels); 123 if (row) *m = *(m-nChannels);
124 m += nChannels; 124 m += nChannels;
125 row++; 125 row++;
126 if (row >= nRows) break; 126 if (row >= nRows) break;
127 } 127 }
128 break; 128 break;
129 129
130 case 0x02: 130 case 0x02:
131 if (xx < row) *m = pat[nChannels*xx]; 131 if (xx < row) *m = pat[nChannels*xx];
132 m += nChannels; 132 m += nChannels;
133 row++; 133 row++;
134 break; 134 break;
135 135
136 case 0x03: 136 case 0x03:
137 { 137 {
138 cmd.note = (xx & 0x01) ? lpTracks[pos++] : 0; 138 cmd.note = (xx & 0x01) ? lpTracks[pos++] : 0;
139 cmd.instr = (xx & 0x02) ? lpTracks[pos++] : 0; 139 cmd.instr = (xx & 0x02) ? lpTracks[pos++] : 0;
140 cmd.volcmd = cmd.vol = 0; 140 cmd.volcmd = cmd.vol = 0;
141 cmd.command = cmd.param = 0; 141 cmd.command = cmd.param = 0;
142 if ((cmd.note < 120-12) && (cmd.note)) cmd.note += 12; 142 if ((cmd.note < 120-12) && (cmd.note)) cmd.note += 12;
143 UINT volume = (xx & 0x04) ? lpTracks[pos++] : 0; 143 UINT volume = (xx & 0x04) ? lpTracks[pos++] : 0;
144 UINT commands = (xx & 0x08) ? lpTracks[pos++] : 0; 144 UINT commands = (xx & 0x08) ? lpTracks[pos++] : 0;
145 UINT command1 = commands & 0x0F; 145 UINT command1 = commands & 0x0F;
146 UINT command2 = commands & 0xF0; 146 UINT command2 = commands & 0xF0;
147 UINT param1 = (xx & 0x10) ? lpTracks[pos++] : 0; 147 UINT param1 = (xx & 0x10) ? lpTracks[pos++] : 0;
148 UINT param2 = (xx & 0x20) ? lpTracks[pos++] : 0; 148 UINT param2 = (xx & 0x20) ? lpTracks[pos++] : 0;
149 if ((command1 == 0x0E) && ((param1 & 0xF0) == 0xF0) && (!command2)) 149 if ((command1 == 0x0E) && ((param1 & 0xF0) == 0xF0) && (!command2))
150 { 150 {
151 param1 = ((param1 & 0x0F) << 8) | param2; 151 param1 = ((param1 & 0x0F) << 8) | param2;
152 command1 = 0xEF; 152 command1 = 0xEF;
153 command2 = param2 = 0; 153 command2 = param2 = 0;
154 } 154 }
155 if (volume) 155 if (volume)
156 { 156 {
157 cmd.volcmd = VOLCMD_VOLUME; 157 cmd.volcmd = VOLCMD_VOLUME;
158 cmd.vol = (volume+1) >> 2; 158 cmd.vol = (volume+1) >> 2;
159 } 159 }
160 ConvertMDLCommand(&cmd, command1, param1); 160 ConvertMDLCommand(&cmd, command1, param1);
161 if ((cmd.command != CMD_SPEED) 161 if ((cmd.command != CMD_SPEED)
162 && (cmd.command != CMD_TEMPO) 162 && (cmd.command != CMD_TEMPO)
163 && (cmd.command != CMD_PATTERNBREAK)) 163 && (cmd.command != CMD_PATTERNBREAK))
164 ConvertMDLCommand(&cmd, command2, param2); 164 ConvertMDLCommand(&cmd, command2, param2);
165 *m = cmd; 165 *m = cmd;
166 m += nChannels; 166 m += nChannels;
167 row++; 167 row++;
168 } 168 }
169 break; 169 break;
170 170
171 // Empty Slots 171 // Empty Slots
172 default: 172 default:
173 row += xx+1; 173 row += xx+1;
174 m += (xx+1)*nChannels; 174 m += (xx+1)*nChannels;
175 if (row >= nRows) break; 175 if (row >= nRows) break;
176 } 176 }
177 } 177 }
178} 178}
179 179
180 180
181 181
182BOOL CSoundFile::ReadMDL(const BYTE *lpStream, DWORD dwMemLength) 182BOOL CSoundFile::ReadMDL(const BYTE *lpStream, DWORD dwMemLength)
183//--------------------------------------------------------------- 183//---------------------------------------------------------------
184{ 184{
185 DWORD dwMemPos, dwPos, blocklen, dwTrackPos; 185 DWORD dwMemPos, dwPos, blocklen, dwTrackPos;
186 const MDLSONGHEADER *pmsh = (const MDLSONGHEADER *)lpStream; 186 const MDLSONGHEADER *pmsh = (const MDLSONGHEADER *)lpStream;
187 MDLINFOBLOCK *pmib; 187 MDLINFOBLOCK *pmib;
188 MDLPATTERNDATA *pmpd; 188 MDLPATTERNDATA *pmpd;
189 UINT i,j, norders = 0, npatterns = 0, ntracks = 0; 189 UINT i,j, norders = 0, npatterns = 0, ntracks = 0;
190 UINT ninstruments = 0, nsamples = 0; 190 UINT ninstruments = 0, nsamples = 0;
191 WORD block; 191 WORD block;
192 WORD patterntracks[MAX_PATTERNS*32]; 192 WORD patterntracks[MAX_PATTERNS*32];
193 BYTE smpinfo[MAX_SAMPLES]; 193 BYTE smpinfo[MAX_SAMPLES];
194 BYTE insvolenv[MAX_INSTRUMENTS]; 194 BYTE insvolenv[MAX_INSTRUMENTS];
195 BYTE inspanenv[MAX_INSTRUMENTS]; 195 BYTE inspanenv[MAX_INSTRUMENTS];
196 LPCBYTE pvolenv, ppanenv, ppitchenv; 196 LPCBYTE pvolenv, ppanenv, ppitchenv;
197 UINT nvolenv, npanenv, npitchenv; 197 UINT nvolenv, npanenv, npitchenv;
198 198
199 if ((!lpStream) || (dwMemLength < 1024)) return FALSE; 199 if ((!lpStream) || (dwMemLength < 1024)) return FALSE;
200 if ((pmsh->id != 0x4C444D44) || ((pmsh->version & 0xF0) > 0x10)) return FALSE; 200 if ((pmsh->id != 0x4C444D44) || ((pmsh->version & 0xF0) > 0x10)) return FALSE;
201 memset(patterntracks, 0, sizeof(patterntracks)); 201 memset(patterntracks, 0, sizeof(patterntracks));
202 memset(smpinfo, 0, sizeof(smpinfo)); 202 memset(smpinfo, 0, sizeof(smpinfo));
203 memset(insvolenv, 0, sizeof(insvolenv)); 203 memset(insvolenv, 0, sizeof(insvolenv));
204 memset(inspanenv, 0, sizeof(inspanenv)); 204 memset(inspanenv, 0, sizeof(inspanenv));
205 dwMemPos = 5; 205 dwMemPos = 5;
206 dwTrackPos = 0; 206 dwTrackPos = 0;
207 pvolenv = ppanenv = ppitchenv = NULL; 207 pvolenv = ppanenv = ppitchenv = NULL;
208 nvolenv = npanenv = npitchenv = 0; 208 nvolenv = npanenv = npitchenv = 0;
209 m_nSamples = m_nInstruments = 0; 209 m_nSamples = m_nInstruments = 0;
210 while (dwMemPos+6 < dwMemLength) 210 while (dwMemPos+6 < dwMemLength)
211 { 211 {
212 block = *((WORD *)(lpStream+dwMemPos)); 212 block = *((WORD *)(lpStream+dwMemPos));
213 blocklen = *((DWORD *)(lpStream+dwMemPos+2)); 213 blocklen = *((DWORD *)(lpStream+dwMemPos+2));
214 dwMemPos += 6; 214 dwMemPos += 6;
215 if (dwMemPos + blocklen > dwMemLength) 215 if (dwMemPos + blocklen > dwMemLength)
216 { 216 {
217 if (dwMemPos == 11) return FALSE; 217 if (dwMemPos == 11) return FALSE;
218 break; 218 break;
219 } 219 }
220 switch(block) 220 switch(block)
221 { 221 {
222 // IN: infoblock 222 // IN: infoblock
223 case 0x4E49: 223 case 0x4E49:
224 pmib = (MDLINFOBLOCK *)(lpStream+dwMemPos); 224 pmib = (MDLINFOBLOCK *)(lpStream+dwMemPos);
225 memcpy(m_szNames[0], pmib->songname, 32); 225 memcpy(m_szNames[0], pmib->songname, 32);
226 norders = pmib->norders; 226 norders = pmib->norders;
227 if (norders > MAX_ORDERS) norders = MAX_ORDERS; 227 if (norders > MAX_ORDERS) norders = MAX_ORDERS;
228 m_nRestartPos = pmib->repeatpos; 228 m_nRestartPos = pmib->repeatpos;
229 m_nDefaultGlobalVolume = pmib->globalvol; 229 m_nDefaultGlobalVolume = pmib->globalvol;
230 m_nDefaultTempo = pmib->tempo; 230 m_nDefaultTempo = pmib->tempo;
231 m_nDefaultSpeed = pmib->speed; 231 m_nDefaultSpeed = pmib->speed;
232 m_nChannels = 4; 232 m_nChannels = 4;
233 for (i=0; i<32; i++) 233 for (i=0; i<32; i++)
234 { 234 {
235 ChnSettings[i].nVolume = 64; 235 ChnSettings[i].nVolume = 64;
236 ChnSettings[i].nPan = (pmib->channelinfo[i] & 0x7F) << 1; 236 ChnSettings[i].nPan = (pmib->channelinfo[i] & 0x7F) << 1;
237 if (pmib->channelinfo[i] & 0x80) 237 if (pmib->channelinfo[i] & 0x80)
238 ChnSettings[i].dwFlags |= CHN_MUTE; 238 ChnSettings[i].dwFlags |= CHN_MUTE;
239 else 239 else
240 m_nChannels = i+1; 240 m_nChannels = i+1;
241 } 241 }
242 for (j=0; j<norders; j++) Order[j] = pmib->seq[j]; 242 for (j=0; j<norders; j++) Order[j] = pmib->seq[j];
243 break; 243 break;
244 // ME: song message 244 // ME: song message
245 case 0x454D: 245 case 0x454D:
246 if (blocklen) 246 if (blocklen)
247 { 247 {
248 if (m_lpszSongComments) delete m_lpszSongComments; 248 if (m_lpszSongComments) delete [] m_lpszSongComments;
249 m_lpszSongComments = new char[blocklen]; 249 m_lpszSongComments = new char[blocklen];
250 if (m_lpszSongComments) 250 if (m_lpszSongComments)
251 { 251 {
252 memcpy(m_lpszSongComments, lpStream+dwMemPos, blocklen); 252 memcpy(m_lpszSongComments, lpStream+dwMemPos, blocklen);
253 m_lpszSongComments[blocklen-1] = 0; 253 m_lpszSongComments[blocklen-1] = 0;
254 } 254 }
255 } 255 }
256 break; 256 break;
257 // PA: Pattern Data 257 // PA: Pattern Data
258 case 0x4150: 258 case 0x4150:
259 npatterns = lpStream[dwMemPos]; 259 npatterns = lpStream[dwMemPos];
260 if (npatterns > MAX_PATTERNS) npatterns = MAX_PATTERNS; 260 if (npatterns > MAX_PATTERNS) npatterns = MAX_PATTERNS;
261 dwPos = dwMemPos + 1; 261 dwPos = dwMemPos + 1;
262 for (i=0; i<npatterns; i++) 262 for (i=0; i<npatterns; i++)
263 { 263 {
264 if (dwPos+18 >= dwMemLength) break; 264 if (dwPos+18 >= dwMemLength) break;
265 pmpd = (MDLPATTERNDATA *)(lpStream + dwPos); 265 pmpd = (MDLPATTERNDATA *)(lpStream + dwPos);
266 if (pmpd->channels > 32) break; 266 if (pmpd->channels > 32) break;
267 PatternSize[i] = pmpd->lastrow+1; 267 PatternSize[i] = pmpd->lastrow+1;
268 if (m_nChannels < pmpd->channels) m_nChannels = pmpd->channels; 268 if (m_nChannels < pmpd->channels) m_nChannels = pmpd->channels;
269 dwPos += 18 + 2*pmpd->channels; 269 dwPos += 18 + 2*pmpd->channels;
270 for (j=0; j<pmpd->channels; j++) 270 for (j=0; j<pmpd->channels; j++)
271 { 271 {
272 patterntracks[i*32+j] = pmpd->data[j]; 272 patterntracks[i*32+j] = pmpd->data[j];
273 } 273 }
274 } 274 }
275 break; 275 break;
276 // TR: Track Data 276 // TR: Track Data
277 case 0x5254: 277 case 0x5254:
278 if (dwTrackPos) break; 278 if (dwTrackPos) break;
279 ntracks = *((WORD *)(lpStream+dwMemPos)); 279 ntracks = *((WORD *)(lpStream+dwMemPos));
280 dwTrackPos = dwMemPos+2; 280 dwTrackPos = dwMemPos+2;
281 break; 281 break;
282 // II: Instruments 282 // II: Instruments
283 case 0x4949: 283 case 0x4949:
284 ninstruments = lpStream[dwMemPos]; 284 ninstruments = lpStream[dwMemPos];
285 dwPos = dwMemPos+1; 285 dwPos = dwMemPos+1;
286 for (i=0; i<ninstruments; i++) 286 for (i=0; i<ninstruments; i++)
287 { 287 {
288 UINT nins = lpStream[dwPos]; 288 UINT nins = lpStream[dwPos];
289 if ((nins >= MAX_INSTRUMENTS) || (!nins)) break; 289 if ((nins >= MAX_INSTRUMENTS) || (!nins)) break;
290 if (m_nInstruments < nins) m_nInstruments = nins; 290 if (m_nInstruments < nins) m_nInstruments = nins;
291 if (!Headers[nins]) 291 if (!Headers[nins])
292 { 292 {
293 UINT note = 12; 293 UINT note = 12;
294 if ((Headers[nins] = new INSTRUMENTHEADER) == NULL) break; 294 if ((Headers[nins] = new INSTRUMENTHEADER) == NULL) break;
295 INSTRUMENTHEADER *penv = Headers[nins]; 295 INSTRUMENTHEADER *penv = Headers[nins];
296 memset(penv, 0, sizeof(INSTRUMENTHEADER)); 296 memset(penv, 0, sizeof(INSTRUMENTHEADER));
297 memcpy(penv->name, lpStream+dwPos+2, 32); 297 memcpy(penv->name, lpStream+dwPos+2, 32);
298 penv->nGlobalVol = 64; 298 penv->nGlobalVol = 64;
299 penv->nPPC = 5*12; 299 penv->nPPC = 5*12;
300 for (j=0; j<lpStream[dwPos+1]; j++) 300 for (j=0; j<lpStream[dwPos+1]; j++)
301 { 301 {
302 const BYTE *ps = lpStream+dwPos+34+14*j; 302 const BYTE *ps = lpStream+dwPos+34+14*j;
303 while ((note < (UINT)(ps[1]+12)) && (note < 120)) 303 while ((note < (UINT)(ps[1]+12)) && (note < 120))
304 { 304 {
305 penv->NoteMap[note] = note+1; 305 penv->NoteMap[note] = note+1;
306 if (ps[0] < MAX_SAMPLES) 306 if (ps[0] < MAX_SAMPLES)
307 { 307 {
308 int ismp = ps[0]; 308 int ismp = ps[0];
309 penv->Keyboard[note] = ps[0]; 309 penv->Keyboard[note] = ps[0];
310 Ins[ismp].nVolume = ps[2]; 310 Ins[ismp].nVolume = ps[2];
311 Ins[ismp].nPan = ps[4] << 1; 311 Ins[ismp].nPan = ps[4] << 1;
312 Ins[ismp].nVibType = ps[11]; 312 Ins[ismp].nVibType = ps[11];
313 Ins[ismp].nVibSweep = ps[10]; 313 Ins[ismp].nVibSweep = ps[10];
314 Ins[ismp].nVibDepth = ps[9]; 314 Ins[ismp].nVibDepth = ps[9];
315 Ins[ismp].nVibRate = ps[8]; 315 Ins[ismp].nVibRate = ps[8];
316 } 316 }
317 penv->nFadeOut = (ps[7] << 8) | ps[6]; 317 penv->nFadeOut = (ps[7] << 8) | ps[6];
318 if (penv->nFadeOut == 0xFFFF) penv->nFadeOut = 0; 318 if (penv->nFadeOut == 0xFFFF) penv->nFadeOut = 0;
319 note++; 319 note++;
320 } 320 }
321 // Use volume envelope ? 321 // Use volume envelope ?
322 if (ps[3] & 0x80) 322 if (ps[3] & 0x80)
323 { 323 {
324 penv->dwFlags |= ENV_VOLUME; 324 penv->dwFlags |= ENV_VOLUME;
325 insvolenv[nins] = (ps[3] & 0x3F) + 1; 325 insvolenv[nins] = (ps[3] & 0x3F) + 1;
326 } 326 }
327 // Use panning envelope ? 327 // Use panning envelope ?
328 if (ps[5] & 0x80) 328 if (ps[5] & 0x80)
329 { 329 {
330 penv->dwFlags |= ENV_PANNING; 330 penv->dwFlags |= ENV_PANNING;
331 inspanenv[nins] = (ps[5] & 0x3F) + 1; 331 inspanenv[nins] = (ps[5] & 0x3F) + 1;
332 } 332 }
333 } 333 }
334 } 334 }
335 dwPos += 34 + 14*lpStream[dwPos+1]; 335 dwPos += 34 + 14*lpStream[dwPos+1];
336 } 336 }
337 for (j=1; j<=m_nInstruments; j++) if (!Headers[j]) 337 for (j=1; j<=m_nInstruments; j++) if (!Headers[j])
338 { 338 {
339 Headers[j] = new INSTRUMENTHEADER; 339 Headers[j] = new INSTRUMENTHEADER;
340 if (Headers[j]) memset(Headers[j], 0, sizeof(INSTRUMENTHEADER)); 340 if (Headers[j]) memset(Headers[j], 0, sizeof(INSTRUMENTHEADER));
341 } 341 }
342 break; 342 break;
343 // VE: Volume Envelope 343 // VE: Volume Envelope
344 case 0x4556: 344 case 0x4556:
345 if ((nvolenv = lpStream[dwMemPos]) == 0) break; 345 if ((nvolenv = lpStream[dwMemPos]) == 0) break;
346 if (dwMemPos + nvolenv*32 + 1 <= dwMemLength) pvolenv = lpStream + dwMemPos + 1; 346 if (dwMemPos + nvolenv*32 + 1 <= dwMemLength) pvolenv = lpStream + dwMemPos + 1;
347 break; 347 break;
348 // PE: Panning Envelope 348 // PE: Panning Envelope
349 case 0x4550: 349 case 0x4550:
350 if ((npanenv = lpStream[dwMemPos]) == 0) break; 350 if ((npanenv = lpStream[dwMemPos]) == 0) break;
351 if (dwMemPos + npanenv*32 + 1 <= dwMemLength) ppanenv = lpStream + dwMemPos + 1; 351 if (dwMemPos + npanenv*32 + 1 <= dwMemLength) ppanenv = lpStream + dwMemPos + 1;
352 break; 352 break;
353 // FE: Pitch Envelope 353 // FE: Pitch Envelope
354 case 0x4546: 354 case 0x4546:
355 if ((npitchenv = lpStream[dwMemPos]) == 0) break; 355 if ((npitchenv = lpStream[dwMemPos]) == 0) break;
356 if (dwMemPos + npitchenv*32 + 1 <= dwMemLength) ppitchenv = lpStream + dwMemPos + 1; 356 if (dwMemPos + npitchenv*32 + 1 <= dwMemLength) ppitchenv = lpStream + dwMemPos + 1;
357 break; 357 break;
358 // IS: Sample Infoblock 358 // IS: Sample Infoblock
359 case 0x5349: 359 case 0x5349:
360 nsamples = lpStream[dwMemPos]; 360 nsamples = lpStream[dwMemPos];
361 dwPos = dwMemPos+1; 361 dwPos = dwMemPos+1;
362 for (i=0; i<nsamples; i++, dwPos += 59) 362 for (i=0; i<nsamples; i++, dwPos += 59)
363 { 363 {
364 UINT nins = lpStream[dwPos]; 364 UINT nins = lpStream[dwPos];
365 if ((nins >= MAX_SAMPLES) || (!nins)) continue; 365 if ((nins >= MAX_SAMPLES) || (!nins)) continue;
366 if (m_nSamples < nins) m_nSamples = nins; 366 if (m_nSamples < nins) m_nSamples = nins;
367 MODINSTRUMENT *pins = &Ins[nins]; 367 MODINSTRUMENT *pins = &Ins[nins];
368 memcpy(m_szNames[nins], lpStream+dwPos+1, 32); 368 memcpy(m_szNames[nins], lpStream+dwPos+1, 32);
369 memcpy(pins->name, lpStream+dwPos+33, 8); 369 memcpy(pins->name, lpStream+dwPos+33, 8);
370 pins->nC4Speed = *((DWORD *)(lpStream+dwPos+41)); 370 pins->nC4Speed = *((DWORD *)(lpStream+dwPos+41));
371 pins->nLength = *((DWORD *)(lpStream+dwPos+45)); 371 pins->nLength = *((DWORD *)(lpStream+dwPos+45));
372 pins->nLoopStart = *((DWORD *)(lpStream+dwPos+49)); 372 pins->nLoopStart = *((DWORD *)(lpStream+dwPos+49));
373 pins->nLoopEnd = pins->nLoopStart + *((DWORD *)(lpStream+dwPos+53)); 373 pins->nLoopEnd = pins->nLoopStart + *((DWORD *)(lpStream+dwPos+53));
374 if (pins->nLoopEnd > pins->nLoopStart) pins->uFlags |= CHN_LOOP; 374 if (pins->nLoopEnd > pins->nLoopStart) pins->uFlags |= CHN_LOOP;
375 pins->nGlobalVol = 64; 375 pins->nGlobalVol = 64;
376 if (lpStream[dwPos+58] & 0x01) 376 if (lpStream[dwPos+58] & 0x01)
377 { 377 {
378 pins->uFlags |= CHN_16BIT; 378 pins->uFlags |= CHN_16BIT;
379 pins->nLength >>= 1; 379 pins->nLength >>= 1;
380 pins->nLoopStart >>= 1; 380 pins->nLoopStart >>= 1;
381 pins->nLoopEnd >>= 1; 381 pins->nLoopEnd >>= 1;
382 } 382 }
383 if (lpStream[dwPos+58] & 0x02) pins->uFlags |= CHN_PINGPONGLOOP; 383 if (lpStream[dwPos+58] & 0x02) pins->uFlags |= CHN_PINGPONGLOOP;
384 smpinfo[nins] = (lpStream[dwPos+58] >> 2) & 3; 384 smpinfo[nins] = (lpStream[dwPos+58] >> 2) & 3;
385 } 385 }
386 break; 386 break;
387 // SA: Sample Data 387 // SA: Sample Data
388 case 0x4153: 388 case 0x4153:
389 dwPos = dwMemPos; 389 dwPos = dwMemPos;
390 for (i=1; i<=m_nSamples; i++) if ((Ins[i].nLength) && (!Ins[i].pSample) && (smpinfo[i] != 3) && (dwPos < dwMemLength)) 390 for (i=1; i<=m_nSamples; i++) if ((Ins[i].nLength) && (!Ins[i].pSample) && (smpinfo[i] != 3) && (dwPos < dwMemLength))
391 { 391 {
392 MODINSTRUMENT *pins = &Ins[i]; 392 MODINSTRUMENT *pins = &Ins[i];
393 UINT flags = (pins->uFlags & CHN_16BIT) ? RS_PCM16S : RS_PCM8S; 393 UINT flags = (pins->uFlags & CHN_16BIT) ? RS_PCM16S : RS_PCM8S;
394 if (!smpinfo[i]) 394 if (!smpinfo[i])
395 { 395 {
396 dwPos += ReadSample(pins, flags, (LPSTR)(lpStream+dwPos), dwMemLength - dwPos); 396 dwPos += ReadSample(pins, flags, (LPSTR)(lpStream+dwPos), dwMemLength - dwPos);
397 } else 397 } else
398 { 398 {
399 DWORD dwLen = *((DWORD *)(lpStream+dwPos)); 399 DWORD dwLen = *((DWORD *)(lpStream+dwPos));
400 dwPos += 4; 400 dwPos += 4;
401 if ((dwPos+dwLen <= dwMemLength) && (dwLen > 4)) 401 if ((dwPos+dwLen <= dwMemLength) && (dwLen > 4))
402 { 402 {
403 flags = (pins->uFlags & CHN_16BIT) ? RS_MDL16 : RS_MDL8; 403 flags = (pins->uFlags & CHN_16BIT) ? RS_MDL16 : RS_MDL8;
404 ReadSample(pins, flags, (LPSTR)(lpStream+dwPos), dwLen); 404 ReadSample(pins, flags, (LPSTR)(lpStream+dwPos), dwLen);
405 } 405 }
406 dwPos += dwLen; 406 dwPos += dwLen;
407 } 407 }
408 } 408 }
409 break; 409 break;
410 } 410 }
411 dwMemPos += blocklen; 411 dwMemPos += blocklen;
412 } 412 }
413 // Unpack Patterns 413 // Unpack Patterns
414 if ((dwTrackPos) && (npatterns) && (m_nChannels) && (ntracks)) 414 if ((dwTrackPos) && (npatterns) && (m_nChannels) && (ntracks))
415 { 415 {
416 for (UINT ipat=0; ipat<npatterns; ipat++) 416 for (UINT ipat=0; ipat<npatterns; ipat++)
417 { 417 {
418 if ((Patterns[ipat] = AllocatePattern(PatternSize[ipat], m_nChannels)) == NULL) break; 418 if ((Patterns[ipat] = AllocatePattern(PatternSize[ipat], m_nChannels)) == NULL) break;
419 for (UINT chn=0; chn<m_nChannels; chn++) if ((patterntracks[ipat*32+chn]) && (patterntracks[ipat*32+chn] <= ntracks)) 419 for (UINT chn=0; chn<m_nChannels; chn++) if ((patterntracks[ipat*32+chn]) && (patterntracks[ipat*32+chn] <= ntracks))
420 { 420 {
421 MODCOMMAND *m = Patterns[ipat] + chn; 421 MODCOMMAND *m = Patterns[ipat] + chn;
422 UnpackMDLTrack(m, m_nChannels, PatternSize[ipat], patterntracks[ipat*32+chn], lpStream+dwTrackPos); 422 UnpackMDLTrack(m, m_nChannels, PatternSize[ipat], patterntracks[ipat*32+chn], lpStream+dwTrackPos);
423 } 423 }
424 } 424 }
425 } 425 }
426 // Set up envelopes 426 // Set up envelopes
427 for (UINT iIns=1; iIns<=m_nInstruments; iIns++) if (Headers[iIns]) 427 for (UINT iIns=1; iIns<=m_nInstruments; iIns++) if (Headers[iIns])
428 { 428 {
429 INSTRUMENTHEADER *penv = Headers[iIns]; 429 INSTRUMENTHEADER *penv = Headers[iIns];
430 // Setup volume envelope 430 // Setup volume envelope
431 if ((nvolenv) && (pvolenv) && (insvolenv[iIns])) 431 if ((nvolenv) && (pvolenv) && (insvolenv[iIns]))
432 { 432 {
433 LPCBYTE pve = pvolenv; 433 LPCBYTE pve = pvolenv;
434 for (UINT nve=0; nve<nvolenv; nve++, pve+=33) if (pve[0]+1 == insvolenv[iIns]) 434 for (UINT nve=0; nve<nvolenv; nve++, pve+=33) if (pve[0]+1 == insvolenv[iIns])
435 { 435 {
436 WORD vtick = 1; 436 WORD vtick = 1;
437 penv->nVolEnv = 15; 437 penv->nVolEnv = 15;
438 for (UINT iv=0; iv<15; iv++) 438 for (UINT iv=0; iv<15; iv++)
439 { 439 {
440 if (iv) vtick += pve[iv*2+1]; 440 if (iv) vtick += pve[iv*2+1];
441 penv->VolPoints[iv] = vtick; 441 penv->VolPoints[iv] = vtick;
442 penv->VolEnv[iv] = pve[iv*2+2]; 442 penv->VolEnv[iv] = pve[iv*2+2];
443 if (!pve[iv*2+1]) 443 if (!pve[iv*2+1])
444 { 444 {
445 penv->nVolEnv = iv+1; 445 penv->nVolEnv = iv+1;
446 break; 446 break;
447 } 447 }
448 } 448 }
449 penv->nVolSustainBegin = penv->nVolSustainEnd = pve[31] & 0x0F; 449 penv->nVolSustainBegin = penv->nVolSustainEnd = pve[31] & 0x0F;
450 if (pve[31] & 0x10) penv->dwFlags |= ENV_VOLSUSTAIN; 450 if (pve[31] & 0x10) penv->dwFlags |= ENV_VOLSUSTAIN;
451 if (pve[31] & 0x20) penv->dwFlags |= ENV_VOLLOOP; 451 if (pve[31] & 0x20) penv->dwFlags |= ENV_VOLLOOP;
452 penv->nVolLoopStart = pve[32] & 0x0F; 452 penv->nVolLoopStart = pve[32] & 0x0F;
453 penv->nVolLoopEnd = pve[32] >> 4; 453 penv->nVolLoopEnd = pve[32] >> 4;
454 } 454 }
455 } 455 }
456 // Setup panning envelope 456 // Setup panning envelope
457 if ((npanenv) && (ppanenv) && (inspanenv[iIns])) 457 if ((npanenv) && (ppanenv) && (inspanenv[iIns]))
458 { 458 {
459 LPCBYTE ppe = ppanenv; 459 LPCBYTE ppe = ppanenv;
460 for (UINT npe=0; npe<npanenv; npe++, ppe+=33) if (ppe[0]+1 == inspanenv[iIns]) 460 for (UINT npe=0; npe<npanenv; npe++, ppe+=33) if (ppe[0]+1 == inspanenv[iIns])
461 { 461 {
462 WORD vtick = 1; 462 WORD vtick = 1;
463 penv->nPanEnv = 15; 463 penv->nPanEnv = 15;
464 for (UINT iv=0; iv<15; iv++) 464 for (UINT iv=0; iv<15; iv++)
465 { 465 {
466 if (iv) vtick += ppe[iv*2+1]; 466 if (iv) vtick += ppe[iv*2+1];
467 penv->PanPoints[iv] = vtick; 467 penv->PanPoints[iv] = vtick;
468 penv->PanEnv[iv] = ppe[iv*2+2]; 468 penv->PanEnv[iv] = ppe[iv*2+2];
469 if (!ppe[iv*2+1]) 469 if (!ppe[iv*2+1])
470 { 470 {
471 penv->nPanEnv = iv+1; 471 penv->nPanEnv = iv+1;
472 break; 472 break;
473 } 473 }
474 } 474 }
475 if (ppe[31] & 0x10) penv->dwFlags |= ENV_PANSUSTAIN; 475 if (ppe[31] & 0x10) penv->dwFlags |= ENV_PANSUSTAIN;
476 if (ppe[31] & 0x20) penv->dwFlags |= ENV_PANLOOP; 476 if (ppe[31] & 0x20) penv->dwFlags |= ENV_PANLOOP;
477 penv->nPanLoopStart = ppe[32] & 0x0F; 477 penv->nPanLoopStart = ppe[32] & 0x0F;
478 penv->nPanLoopEnd = ppe[32] >> 4; 478 penv->nPanLoopEnd = ppe[32] >> 4;
479 } 479 }
480 } 480 }
481 } 481 }
482 m_dwSongFlags |= SONG_LINEARSLIDES; 482 m_dwSongFlags |= SONG_LINEARSLIDES;
483 m_nType = MOD_TYPE_MDL; 483 m_nType = MOD_TYPE_MDL;
484 return TRUE; 484 return TRUE;
485} 485}
486 486
487 487
488///////////////////////////////////////////////////////////////////////// 488/////////////////////////////////////////////////////////////////////////
489// MDL Sample Unpacking 489// MDL Sample Unpacking
490 490
491// MDL Huffman ReadBits compression 491// MDL Huffman ReadBits compression
492WORD MDLReadBits(DWORD &bitbuf, UINT &bitnum, LPBYTE &ibuf, CHAR n) 492WORD MDLReadBits(DWORD &bitbuf, UINT &bitnum, LPBYTE &ibuf, CHAR n)
493//----------------------------------------------------------------- 493//-----------------------------------------------------------------
494{ 494{
495 WORD v = (WORD)(bitbuf & ((1 << n) - 1) ); 495 WORD v = (WORD)(bitbuf & ((1 << n) - 1) );
496 bitbuf >>= n; 496 bitbuf >>= n;
497 bitnum -= n; 497 bitnum -= n;
498 if (bitnum <= 24) 498 if (bitnum <= 24)
499 { 499 {
500 bitbuf |= (((DWORD)(*ibuf++)) << bitnum); 500 bitbuf |= (((DWORD)(*ibuf++)) << bitnum);
501 bitnum += 8; 501 bitnum += 8;
502 } 502 }
503 return v; 503 return v;
504} 504}
505 505
506 506