@@ -286,66 +286,49 @@ BOOL CSoundFile::ReadPSM(LPCBYTE lpStream, DWORD dwMemLength)
286286if  ((Patterns[nPat] = AllocatePattern (nRows, m_nChannels)) == NULL ) break ;
287287MODCOMMAND *m = Patterns[nPat];
288288BYTE *p = pPsmPat->data ;
289+ MODCOMMAND *sp, dummy;
289290UINT pos = 0 ;
290291UINT row = 0 ;
291- UINT oldch = 0 ;
292- BOOL bNewRow = FALSE ;
292+ UINT rowlim;
293293#ifdef  PSM_LOG
294294Log (" Pattern %d at offset 0x%04X\n " 
295295#endif 
296+ UINT flags, ch;
297+ rowlim = bswapLE16 (pPsmPat->reserved1 )-2 ;
296298while  ((row < nRows) && (pos+1  < len))
297299{
298- UINT flags = p[pos++];
299- UINT ch = p[pos++];
300- 
301- #ifdef  PSM_LOG
302- // Log("flags+ch: %02X.%02X\n", flags, ch);
303- #endif 
304- if  (((flags & 0xf0 ) == 0x10 ) && (ch <= oldch) /* && (!bNewRow)*/ 
305- {
306- if  ((pos+1 <len) && (!(p[pos] & 0x0f )) && (p[pos+1 ] < m_nChannels))
307- {
308- #ifdef  PSM_LOG
309- // if (!nPat) Log("Continuing on new row\n");
310- #endif 
311- row++;
312- m += m_nChannels;
313- oldch = ch;
314- continue ;
315- }
316- }
317- if  ((pos >= len) || (row >= nRows)) break ;
318- if  (!(flags & 0xf0 ))
319- {
320- #ifdef  PSM_LOG
321- // if (!nPat) Log("EOR(%d): %02X.%02X\n", row, p[pos], p[pos+1]);
322- #endif 
323- row++;
300+ if  ((pos+1 ) >= rowlim) {
301+ pos = rowlim;
302+ rowlim = (((int )p[pos+1 ])<<8 )
303+ | ((int )p[pos+0 ]);
324304m += m_nChannels;
325- bNewRow = TRUE ;
326- oldch = ch;
327- continue ;
328- }
329- bNewRow = FALSE ;
330- if  (ch >= m_nChannels)
331- {
332- #ifdef  PSM_LOG
333- if  (!nPat) Log (" Invalid channel row=%d (0x%02X.0x%02X)\n " 
334- #endif 
335- ch = 0 ;
305+ row++;
306+ rowlim += pos;
307+ pos += 2 ;
336308}
309+ flags = p[pos++];
310+ ch = p[pos++];
311+ if  (ch >= m_nChannels) {
312+ sp = &dummy;
313+  } else  {
314+ sp = &m[ch];
315+  }
337316//  Note + Instr
317+  if  ((flags & 0x80 ) && (pos+1  < len))
318+  {
319+  UINT note = p[pos++];
320+  note = (note>>4 )*12 +(note&0x0f )+12 +1 ;
321+  if  (note > 0x80 ) note = 0 ;
322+ m[ch].note  = note;
323+  }
338324if  ((flags & 0x40 ) && (pos+1  < len))
339325{
340- UINT note = p[pos++];
341326UINT nins = p[pos++];
342327#ifdef  PSM_LOG
343328// if (!nPat) Log("note+ins: %02X.%02X\n", note, nins);
344329if  ((!nPat) && (nins >= m_nSamples)) Log (" WARNING: invalid instrument number (%d)\n " 
345330#endif 
346- if  ((note) && (note < 0x80 )) note = (note>>4 )*12 +(note&0x0f )+12 +1 ;
347331m[ch].instr  = samplemap[nins];
348- m[ch].note  = note;
349332}
350333//  Volume
351334if  ((flags & 0x20 ) && (pos < len))
@@ -362,13 +345,29 @@ BOOL CSoundFile::ReadPSM(LPCBYTE lpStream, DWORD dwMemLength)
362345switch (command)
363346{
364347//  01: fine volslide up
365- case  0x01 :	command = CMD_VOLUMESLIDE; param |= 0x0f ; break ;
348+ case  0x01 :	command = CMD_VOLUMESLIDE; param |= 0x0f ;
349+ if  (param == 15 ) param=31 ;
350+ break ;
351+  //  02: volslide up
352+  case  0x02 : command = CMD_VOLUMESLIDE; param>>=1 ; param<<=4 ; break ;
353+  //  03: fine volslide down
354+  case  0x03 :	command = CMD_VOLUMESLIDE; param>>=4 ; param |= 0xf0 ;
355+ if  (param == 240 ) param=241 ;
356+ break ;
366357//  04: fine volslide down
367358case  0x04 :	command = CMD_VOLUMESLIDE; param>>=4 ; param |= 0xf0 ; break ;
368359//  0C: portamento up
369360case  0x0C :	command = CMD_PORTAMENTOUP; param = (param+1 )/2 ; break ;
370361//  0E: portamento down
371362case  0x0E :	command = CMD_PORTAMENTODOWN; param = (param+1 )/2 ; break ;
363+ //  0F: tone portamento
364+ case  0x0F :	command = CMD_TONEPORTAMENTO; param = param/4 ; break ;
365+ //  15: vibrato
366+  case  0x15 :	command = CMD_VIBRATO; break ;
367+ //  29: sample offset
368+ case  0x29 :	pos += 2 ; break ;
369+ //  2A: retrigger note
370+ case  0x2A :	command = CMD_RETRIG; break ;
372371//  33: Position Jump
373372case  0x33 :	command = CMD_POSITIONJUMP; break ;
374373//  34: Pattern break
@@ -387,7 +386,6 @@ BOOL CSoundFile::ReadPSM(LPCBYTE lpStream, DWORD dwMemLength)
387386m[ch].command  = (BYTE)command;
388387m[ch].param  = (BYTE)param;
389388}
390- oldch = ch;
391389}
392390#ifdef  PSM_LOG
393391if  (pos < len)
0 commit comments