@@ -152,6 +152,7 @@ bool loadIT(FILE *f, uint32_t filesize)
152152 bool oldFormat = (itHdr .cmwt < 0x200 );
153153 bool songUsesInstruments = !!(itHdr .flags & 4 );
154154 bool oldEffects = !!(itHdr .flags & 16 );
155+ bool compatGxx = !!(itHdr .flags & 32 );
155156
156157 // read order list
157158 for (int32_t i = 0 ; i < MAX_ORDERS ; i ++ )
@@ -664,16 +665,21 @@ bool loadIT(FILE *f, uint32_t filesize)
664665 songTmp .numChannels = MIN ((numChannels + 1 ) & ~1 , MAX_CHANNELS );
665666
666667 // convert pattern data
667-
668+
669+ uint8_t lastInstr [MAX_CHANNELS ], lastGInstr [MAX_CHANNELS ];
668670 uint8_t lastDxy [MAX_CHANNELS ], lastExy [MAX_CHANNELS ], lastFxy [MAX_CHANNELS ];
669671 uint8_t lastJxy [MAX_CHANNELS ], lastKxy [MAX_CHANNELS ], lastLxy [MAX_CHANNELS ];
672+ uint8_t lastOxx [MAX_CHANNELS ];
670673
674+ memset (lastInstr , 0 , sizeof (lastInstr ));
675+ memset (lastGInstr , 0 , sizeof (lastGInstr ));
671676 memset (lastDxy , 0 , sizeof (lastDxy ));
672677 memset (lastExy , 0 , sizeof (lastExy ));
673678 memset (lastFxy , 0 , sizeof (lastFxy ));
674679 memset (lastJxy , 0 , sizeof (lastJxy ));
675680 memset (lastKxy , 0 , sizeof (lastKxy ));
676681 memset (lastLxy , 0 , sizeof (lastLxy ));
682+ memset (lastOxx , 0 , sizeof (lastOxx ));
677683
678684 for (int32_t i = 0 ; i < songTmp .pattNum ; i ++ )
679685 {
@@ -685,6 +691,9 @@ bool loadIT(FILE *f, uint32_t filesize)
685691 {
686692 for (int32_t ch = 0 ; ch < songTmp .numChannels ; ch ++ , p ++ )
687693 {
694+ if (p -> instr > 0 )
695+ lastInstr [ch ] = p -> instr ;
696+
688697 // effect
689698 if (p -> efx != 0 )
690699 {
@@ -803,7 +812,15 @@ bool loadIT(FILE *f, uint32_t filesize)
803812 }
804813 break ;
805814
806- case 'G' : p -> efx = 3 ; break ; // tone portamento
815+ case 'G' : // tone portamento
816+ {
817+ p -> efx = 3 ;
818+
819+ // remove illegal slides (this is not quite right, but good enough)
820+ if (!compatGxx && p -> instr != 0 && p -> instr != lastGInstr [ch ])
821+ p -> efx = p -> efxData = 0 ;
822+ }
823+ break ;
807824
808825 case 'H' : // vibrato
809826 {
@@ -912,7 +929,46 @@ bool loadIT(FILE *f, uint32_t filesize)
912929 }
913930 break ;
914931
915- case 'O' : p -> efx = 0x9 ; break ; // set sample offset
932+ case 'O' : // set sample offset
933+ {
934+ p -> efx = 0x9 ;
935+
936+ if (p -> efxData > 0 )
937+ lastOxx [ch ] = p -> efxData ;
938+
939+ // handle cases where the sample offset is after the end of the sample
940+ if (lastInstr [ch ] > 0 && lastOxx [ch ] > 0 && p -> note > 0 && p -> note <= 96 )
941+ {
942+ instr_t * ins = instrTmp [lastInstr [ch ]];
943+ if (ins != NULL )
944+ {
945+ const uint8_t sample = ins -> note2SampleLUT [p -> note - 1 ];
946+ if (sample < MAX_SMP_PER_INST )
947+ {
948+ sample_t * s = & ins -> smp [sample ];
949+ if (s -> length > 0 )
950+ {
951+ const bool loopEnabled = (GET_LOOPTYPE (s -> flags ) != LOOP_DISABLED );
952+ const uint32_t sampleEnd = loopEnabled ? s -> loopStart + s -> loopLength : s -> length ;
953+
954+ if (lastOxx [ch ]* 256UL >= sampleEnd )
955+ {
956+ if (oldEffects )
957+ {
958+ if (loopEnabled )
959+ p -> efxData = (uint8_t )(sampleEnd >> 8 );
960+ }
961+ else
962+ {
963+ p -> efx = p -> efxData = 0 ;
964+ }
965+ }
966+ }
967+ }
968+ }
969+ }
970+ }
971+ break ;
916972
917973 case 'P' : // panning slide
918974 {
@@ -1044,6 +1100,9 @@ bool loadIT(FILE *f, uint32_t filesize)
10441100 p -> efxData = 0 ;
10451101 }
10461102
1103+ if (p -> instr != 0 && p -> efx != 0x3 )
1104+ lastGInstr [ch ] = p -> instr ;
1105+
10471106 // volume column
10481107 if (p -> vol > 0 )
10491108 {
0 commit comments