Mercurial > audlegacy-plugins
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; |