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

Sync with schism's modplug engine. Suggested by G¸«ärkan Seng¸«än.
author William Pitcock <nenolod@atheme.org>
date Fri, 07 Dec 2007 12:08:47 -0600
parents 6b5a52635b3b
children 6907fc39b53f
comparison
equal deleted inserted replaced
2198:32f9f1e4a9ec 2216:3673c7ec4ea2
74 case 0xB0: param = data & 0x0F; command = CMD_GLOBALVOLSLIDE; break; 74 case 0xB0: param = data & 0x0F; command = CMD_GLOBALVOLSLIDE; break;
75 case 0xF0: param = ((data >> 8) & 0x0F) | 0xA0; break; 75 case 0xF0: param = ((data >> 8) & 0x0F) | 0xA0; break;
76 } 76 }
77 break; 77 break;
78 case 0x0F: command = CMD_SPEED; break; 78 case 0x0F: command = CMD_SPEED; break;
79 case 0x10: if ((param & 0xF0) != 0xE0) { command = CMD_VOLUMESLIDE; if ((param & 0xF0) == 0xF0) param = ((param << 4) | 0x0F); else param >>= 2; } break; 79
80 case 0x20: if ((param & 0xF0) != 0xE0) { command = CMD_VOLUMESLIDE; if ((param & 0xF0) != 0xF0) param >>= 2; } break; 80 case 0x10:
81 if ((param & 0xF0) != 0xE0) {
82 command = CMD_VOLUMESLIDE;
83 if ((param & 0xF0) == 0xF0) {
84 param = ((param << 4) | 0x0F);
85 } else {
86 param >>= 2;
87 if (param > 0xF)
88 param = 0xF;
89 param <<= 4;
90 }
91 }
92 break;
93 case 0x20:
94 if ((param & 0xF0) != 0xE0) {
95 command = CMD_VOLUMESLIDE;
96 if ((param & 0xF0) != 0xF0) {
97 param >>= 2;
98 if (param > 0xF)
99 param = 0xF;
100 }
101 }
102 break;
103
81 case 0x30: command = CMD_RETRIG; break; 104 case 0x30: command = CMD_RETRIG; break;
82 case 0x40: command = CMD_TREMOLO; break; 105 case 0x40: command = CMD_TREMOLO; break;
83 case 0x50: command = CMD_TREMOR; break; 106 case 0x50: command = CMD_TREMOR; break;
84 case 0xEF: if (param > 0xFF) param = 0xFF; command = CMD_OFFSET; break; 107 case 0xEF: if (param > 0xFF) param = 0xFF; command = CMD_OFFSET; break;
85 } 108 }
192 BYTE inspanenv[MAX_INSTRUMENTS]; 215 BYTE inspanenv[MAX_INSTRUMENTS];
193 LPCBYTE pvolenv, ppanenv, ppitchenv; 216 LPCBYTE pvolenv, ppanenv, ppitchenv;
194 UINT nvolenv, npanenv, npitchenv; 217 UINT nvolenv, npanenv, npitchenv;
195 218
196 if ((!lpStream) || (dwMemLength < 1024)) return FALSE; 219 if ((!lpStream) || (dwMemLength < 1024)) return FALSE;
197 if ((pmsh->id != 0x4C444D44) || ((pmsh->version & 0xF0) > 0x10)) return FALSE; 220 if ((bswapLE32(pmsh->id) != 0x4C444D44) || ((pmsh->version & 0xF0) > 0x10)) return FALSE;
198 memset(patterntracks, 0, sizeof(patterntracks)); 221 memset(patterntracks, 0, sizeof(patterntracks));
199 memset(smpinfo, 0, sizeof(smpinfo)); 222 memset(smpinfo, 0, sizeof(smpinfo));
200 memset(insvolenv, 0, sizeof(insvolenv)); 223 memset(insvolenv, 0, sizeof(insvolenv));
201 memset(inspanenv, 0, sizeof(inspanenv)); 224 memset(inspanenv, 0, sizeof(inspanenv));
202 dwMemPos = 5; 225 dwMemPos = 5;
203 dwTrackPos = 0; 226 dwTrackPos = 0;
204 pvolenv = ppanenv = ppitchenv = NULL; 227 pvolenv = ppanenv = ppitchenv = NULL;
205 nvolenv = npanenv = npitchenv = 0; 228 nvolenv = npanenv = npitchenv = 0;
206 m_nSamples = m_nInstruments = 0; 229 m_nSamples = m_nInstruments = 0;
230 m_dwSongFlags |= SONG_INSTRUMENTMODE;
207 while (dwMemPos+6 < dwMemLength) 231 while (dwMemPos+6 < dwMemLength)
208 { 232 {
209 block = *((WORD *)(lpStream+dwMemPos)); 233 block = *((WORD *)(lpStream+dwMemPos));
210 blocklen = *((DWORD *)(lpStream+dwMemPos+2)); 234 blocklen = *((DWORD *)(lpStream+dwMemPos+2));
235 block = bswapLE16(block);
236 blocklen = bswapLE32(blocklen);
211 dwMemPos += 6; 237 dwMemPos += 6;
212 if (dwMemPos + blocklen > dwMemLength) 238 if (dwMemPos + blocklen > dwMemLength)
213 { 239 {
214 if (dwMemPos == 11) return FALSE; 240 if (dwMemPos == 11) return FALSE;
215 break; 241 break;
218 { 244 {
219 // IN: infoblock 245 // IN: infoblock
220 case 0x4E49: 246 case 0x4E49:
221 pmib = (MDLINFOBLOCK *)(lpStream+dwMemPos); 247 pmib = (MDLINFOBLOCK *)(lpStream+dwMemPos);
222 memcpy(m_szNames[0], pmib->songname, 32); 248 memcpy(m_szNames[0], pmib->songname, 32);
223 norders = pmib->norders; 249 norders = bswapLE16(pmib->norders);
224 if (norders > MAX_ORDERS) norders = MAX_ORDERS; 250 if (norders > MAX_ORDERS) norders = MAX_ORDERS;
225 m_nRestartPos = pmib->repeatpos; 251 m_nRestartPos = bswapLE16(pmib->repeatpos);
226 m_nDefaultGlobalVolume = pmib->globalvol; 252 m_nDefaultGlobalVolume = pmib->globalvol;
253 if (m_nDefaultGlobalVolume == 255)
254 m_nDefaultGlobalVolume++;
227 m_nDefaultTempo = pmib->tempo; 255 m_nDefaultTempo = pmib->tempo;
228 m_nDefaultSpeed = pmib->speed; 256 m_nDefaultSpeed = pmib->speed;
229 m_nChannels = 4; 257 m_nChannels = 4;
230 for (i=0; i<32; i++) 258 for (i=0; i<32; i++)
231 { 259 {
260 { 288 {
261 if (dwPos+18 >= dwMemLength) break; 289 if (dwPos+18 >= dwMemLength) break;
262 pmpd = (MDLPATTERNDATA *)(lpStream + dwPos); 290 pmpd = (MDLPATTERNDATA *)(lpStream + dwPos);
263 if (pmpd->channels > 32) break; 291 if (pmpd->channels > 32) break;
264 PatternSize[i] = pmpd->lastrow+1; 292 PatternSize[i] = pmpd->lastrow+1;
293 PatternAllocSize[i] = pmpd->lastrow+1;
265 if (m_nChannels < pmpd->channels) m_nChannels = pmpd->channels; 294 if (m_nChannels < pmpd->channels) m_nChannels = pmpd->channels;
266 dwPos += 18 + 2*pmpd->channels; 295 dwPos += 18 + 2*pmpd->channels;
267 for (j=0; j<pmpd->channels; j++) 296 for (j=0; j<pmpd->channels; j++)
268 { 297 {
269 patterntracks[i*32+j] = pmpd->data[j]; 298 patterntracks[i*32+j] = bswapLE16(pmpd->data[j]);
270 } 299 }
271 } 300 }
272 break; 301 break;
273 // TR: Track Data 302 // TR: Track Data
274 case 0x5254: 303 case 0x5254:
275 if (dwTrackPos) break; 304 if (dwTrackPos) break;
276 ntracks = *((WORD *)(lpStream+dwMemPos)); 305 ntracks = *((WORD *)(lpStream+dwMemPos));
306 ntracks = bswapLE16(ntracks);
277 dwTrackPos = dwMemPos+2; 307 dwTrackPos = dwMemPos+2;
278 break; 308 break;
279 // II: Instruments 309 // II: Instruments
280 case 0x4949: 310 case 0x4949:
281 ninstruments = lpStream[dwMemPos]; 311 ninstruments = lpStream[dwMemPos];
290 UINT note = 12; 320 UINT note = 12;
291 if ((Headers[nins] = new INSTRUMENTHEADER) == NULL) break; 321 if ((Headers[nins] = new INSTRUMENTHEADER) == NULL) break;
292 INSTRUMENTHEADER *penv = Headers[nins]; 322 INSTRUMENTHEADER *penv = Headers[nins];
293 memset(penv, 0, sizeof(INSTRUMENTHEADER)); 323 memset(penv, 0, sizeof(INSTRUMENTHEADER));
294 memcpy(penv->name, lpStream+dwPos+2, 32); 324 memcpy(penv->name, lpStream+dwPos+2, 32);
295 penv->nGlobalVol = 64; 325 penv->nGlobalVol = 128;
296 penv->nPPC = 5*12; 326 penv->nPPC = 5*12;
297 for (j=0; j<lpStream[dwPos+1]; j++) 327 for (j=0; j<lpStream[dwPos+1]; j++)
298 { 328 {
299 const BYTE *ps = lpStream+dwPos+34+14*j; 329 const BYTE *ps = lpStream+dwPos+34+14*j;
300 while ((note < (UINT)(ps[1]+12)) && (note < 120)) 330 while ((note < (UINT)(ps[1]+12)) && (note < 120))
363 if (m_nSamples < nins) m_nSamples = nins; 393 if (m_nSamples < nins) m_nSamples = nins;
364 MODINSTRUMENT *pins = &Ins[nins]; 394 MODINSTRUMENT *pins = &Ins[nins];
365 memcpy(m_szNames[nins], lpStream+dwPos+1, 32); 395 memcpy(m_szNames[nins], lpStream+dwPos+1, 32);
366 memcpy(pins->name, lpStream+dwPos+33, 8); 396 memcpy(pins->name, lpStream+dwPos+33, 8);
367 pins->nC4Speed = *((DWORD *)(lpStream+dwPos+41)); 397 pins->nC4Speed = *((DWORD *)(lpStream+dwPos+41));
398 pins->nC4Speed = bswapLE32(pins->nC4Speed);
368 pins->nLength = *((DWORD *)(lpStream+dwPos+45)); 399 pins->nLength = *((DWORD *)(lpStream+dwPos+45));
400 pins->nLength = bswapLE32(pins->nLength);
369 pins->nLoopStart = *((DWORD *)(lpStream+dwPos+49)); 401 pins->nLoopStart = *((DWORD *)(lpStream+dwPos+49));
402 pins->nLoopStart = bswapLE32(pins->nLoopStart);
370 pins->nLoopEnd = pins->nLoopStart + *((DWORD *)(lpStream+dwPos+53)); 403 pins->nLoopEnd = pins->nLoopStart + *((DWORD *)(lpStream+dwPos+53));
404 pins->nLoopEnd = bswapLE32(pins->nLoopEnd);
371 if (pins->nLoopEnd > pins->nLoopStart) pins->uFlags |= CHN_LOOP; 405 if (pins->nLoopEnd > pins->nLoopStart) pins->uFlags |= CHN_LOOP;
372 pins->nGlobalVol = 64; 406 pins->nGlobalVol = 64;
373 if (lpStream[dwPos+58] & 0x01) 407 if (lpStream[dwPos+58] & 0x01)
374 { 408 {
375 pins->uFlags |= CHN_16BIT; 409 pins->uFlags |= CHN_16BIT;
392 { 426 {
393 dwPos += ReadSample(pins, flags, (LPSTR)(lpStream+dwPos), dwMemLength - dwPos); 427 dwPos += ReadSample(pins, flags, (LPSTR)(lpStream+dwPos), dwMemLength - dwPos);
394 } else 428 } else
395 { 429 {
396 DWORD dwLen = *((DWORD *)(lpStream+dwPos)); 430 DWORD dwLen = *((DWORD *)(lpStream+dwPos));
431 dwLen = bswapLE32(dwLen);
397 dwPos += 4; 432 dwPos += 4;
398 if ((dwPos+dwLen <= dwMemLength) && (dwLen > 4)) 433 if ((dwPos+dwLen <= dwMemLength) && (dwLen > 4))
399 { 434 {
400 flags = (pins->uFlags & CHN_16BIT) ? RS_MDL16 : RS_MDL8; 435 flags = (pins->uFlags & CHN_16BIT) ? RS_MDL16 : RS_MDL8;
401 ReadSample(pins, flags, (LPSTR)(lpStream+dwPos), dwLen); 436 ReadSample(pins, flags, (LPSTR)(lpStream+dwPos), dwLen);
429 { 464 {
430 LPCBYTE pve = pvolenv; 465 LPCBYTE pve = pvolenv;
431 for (UINT nve=0; nve<nvolenv; nve++, pve+=33) if (pve[0]+1 == insvolenv[iIns]) 466 for (UINT nve=0; nve<nvolenv; nve++, pve+=33) if (pve[0]+1 == insvolenv[iIns])
432 { 467 {
433 WORD vtick = 1; 468 WORD vtick = 1;
434 penv->nVolEnv = 15; 469 penv->VolEnv.nNodes = 15;
435 for (UINT iv=0; iv<15; iv++) 470 for (UINT iv=0; iv<15; iv++)
436 { 471 {
437 if (iv) vtick += pve[iv*2+1]; 472 if (iv) vtick += pve[iv*2+1];
438 penv->VolPoints[iv] = vtick; 473 penv->VolEnv.Ticks[iv] = vtick;
439 penv->VolEnv[iv] = pve[iv*2+2]; 474 penv->VolEnv.Values[iv] = pve[iv*2+2];
440 if (!pve[iv*2+1]) 475 if (!pve[iv*2+1])
441 { 476 {
442 penv->nVolEnv = iv+1; 477 penv->VolEnv.nNodes = iv+1;
443 break; 478 break;
444 } 479 }
445 } 480 }
446 penv->nVolSustainBegin = penv->nVolSustainEnd = pve[31] & 0x0F; 481 penv->VolEnv.nSustainStart = penv->VolEnv.nSustainEnd = pve[31] & 0x0F;
447 if (pve[31] & 0x10) penv->dwFlags |= ENV_VOLSUSTAIN; 482 if (pve[31] & 0x10) penv->dwFlags |= ENV_VOLSUSTAIN;
448 if (pve[31] & 0x20) penv->dwFlags |= ENV_VOLLOOP; 483 if (pve[31] & 0x20) penv->dwFlags |= ENV_VOLLOOP;
449 penv->nVolLoopStart = pve[32] & 0x0F; 484 penv->VolEnv.nLoopStart = pve[32] & 0x0F;
450 penv->nVolLoopEnd = pve[32] >> 4; 485 penv->VolEnv.nLoopEnd = pve[32] >> 4;
451 } 486 }
452 } 487 }
453 // Setup panning envelope 488 // Setup panning envelope
454 if ((npanenv) && (ppanenv) && (inspanenv[iIns])) 489 if ((npanenv) && (ppanenv) && (inspanenv[iIns]))
455 { 490 {
456 LPCBYTE ppe = ppanenv; 491 LPCBYTE ppe = ppanenv;
457 for (UINT npe=0; npe<npanenv; npe++, ppe+=33) if (ppe[0]+1 == inspanenv[iIns]) 492 for (UINT npe=0; npe<npanenv; npe++, ppe+=33) if (ppe[0]+1 == inspanenv[iIns])
458 { 493 {
459 WORD vtick = 1; 494 WORD vtick = 1;
460 penv->nPanEnv = 15; 495 penv->PanEnv.nNodes = 15;
461 for (UINT iv=0; iv<15; iv++) 496 for (UINT iv=0; iv<15; iv++)
462 { 497 {
463 if (iv) vtick += ppe[iv*2+1]; 498 if (iv) vtick += ppe[iv*2+1];
464 penv->PanPoints[iv] = vtick; 499 penv->PanEnv.Ticks[iv] = vtick;
465 penv->PanEnv[iv] = ppe[iv*2+2]; 500 penv->PanEnv.Values[iv] = ppe[iv*2+2];
466 if (!ppe[iv*2+1]) 501 if (!ppe[iv*2+1])
467 { 502 {
468 penv->nPanEnv = iv+1; 503 penv->PanEnv.nNodes = iv+1;
469 break; 504 break;
470 } 505 }
471 } 506 }
472 if (ppe[31] & 0x10) penv->dwFlags |= ENV_PANSUSTAIN; 507 if (ppe[31] & 0x10) penv->dwFlags |= ENV_PANSUSTAIN;
473 if (ppe[31] & 0x20) penv->dwFlags |= ENV_PANLOOP; 508 if (ppe[31] & 0x20) penv->dwFlags |= ENV_PANLOOP;
474 penv->nPanLoopStart = ppe[32] & 0x0F; 509 penv->PanEnv.nLoopStart = ppe[32] & 0x0F;
475 penv->nPanLoopEnd = ppe[32] >> 4; 510 penv->PanEnv.nLoopEnd = ppe[32] >> 4;
476 } 511 }
477 } 512 }
478 } 513 }
479 m_dwSongFlags |= SONG_LINEARSLIDES; 514 m_dwSongFlags |= SONG_LINEARSLIDES;
480 m_nType = MOD_TYPE_MDL; 515 m_nType = MOD_TYPE_MDL;