1 /*
2  * Copyright (c) 2009, The MilkyTracker Team.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * - Redistributions of source code must retain the above copyright notice,
9  *   this list of conditions and the following disclaimer.
10  * - Redistributions in binary form must reproduce the above copyright
11  *   notice, this list of conditions and the following disclaimer in the
12  *   documentation and/or other materials provided with the distribution.
13  * - Neither the name of the <ORGANIZATION> nor the names of its contributors
14  *   may be used to endorse or promote products derived from this software
15  *   without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 /*
31  *  PlayerIT.cpp
32  *  MilkyPlay IT player. Note that this evolved out of the standard player which
33  *  aims at correct XM replay, so many things might still be not correct for
34  *  impulse tracker. So this code is subject to change.
35  *
36  *
37  */
38 #include "PlayerIT.h"
39 
40 // if we're in background we work on our own state
41 // if not, we're just going to work on the host state
chnstat()42 PlayerIT::TChnState& PlayerIT::TVirtualChannel::chnstat()
43 {
44 	return host ? host->state : state;
45 }
46 
47 #define CHANNEL_FLAGS_DVS				0x10000
48 #define CHANNEL_FLAGS_DFS				0x20000
49 #define CHANNEL_FLAGS_DPS				0x40000
50 #define CHANNEL_FLAGS_FORCE_FORWARD		0x00001
51 #define CHANNEL_FLAGS_FORCE_BACKWARD	0x00002
52 #define CHANNEL_FLAGS_FORCE_BILOOP		0x00004
53 #define CHANNEL_FLAGS_UPDATE_IGNORE		0x00100
54 
55 //#define MINPERIOD (113*4)
56 
57 // must be called after the poscnt has been properly set
58 #define RESETLOOPING \
59 { \
60 	chnInf->loopstart=chnInf->loopcounter=chnInf->execloop=0; \
61 	chnInf->isLooping = false; \
62 	chnInf->loopingValidPosition = poscnt; \
63 }
64 
65 #define RESET_ALL_LOOPING \
66 { \
67 	for (mp_sint32 c = 0; c < numModuleChannels; c++) \
68 	{ \
69 		TModuleChannel *chnInf = &chninfo[c]; \
70 		RESETLOOPING \
71 	} \
72 }
73 
myMod(mp_sint32 a,mp_sint32 b)74 static inline mp_sint32 myMod(mp_sint32 a, mp_sint32 b)
75 {
76 	mp_sint32 r = a % b;
77 	return r < 0 ? b + r : r;
78 }
79 
80 const mp_sint32	PlayerIT::vibtab[32] = {
81 	0,24,49,74,97,120,141,161,
82 	180,197,212,224,235,244,250,253,
83 	255,253,250,244,235,224,212,197,
84 	180,161,141,120,97,74,49,24
85 };
86 
87 const mp_sint32 PlayerIT::finesintab[256] = {
88 	0,  2,  3,  5,  6,  8,  9, 11, 12, 14, 16, 17, 19, 20, 22, 23,
89 	24, 26, 27, 29, 30, 32, 33, 34, 36, 37, 38, 39, 41, 42, 43, 44,
90 	45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 56, 57, 58, 59,
91 	59, 60, 60, 61, 61, 62, 62, 62, 63, 63, 63, 64, 64, 64, 64, 64,
92 	64, 64, 64, 64, 64, 64, 63, 63, 63, 62, 62, 62, 61, 61, 60, 60,
93 	59, 59, 58, 57, 56, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46,
94 	45, 44, 43, 42, 41, 39, 38, 37, 36, 34, 33, 32, 30, 29, 27, 26,
95 	24, 23, 22, 20, 19, 17, 16, 14, 12, 11,  9,  8,  6,  5,  3,  2,
96 	0, -2, -3, -5, -6, -8, -9,-11,-12,-14,-16,-17,-19,-20,-22,-23,
97 	-24,-26,-27,-29,-30,-32,-33,-34,-36,-37,-38,-39,-41,-42,-43,-44,
98 	-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-56,-57,-58,-59,
99 	-59,-60,-60,-61,-61,-62,-62,-62,-63,-63,-63,-64,-64,-64,-64,-64,
100 	-64,-64,-64,-64,-64,-64,-63,-63,-63,-62,-62,-62,-61,-61,-60,-60,
101 	-59,-59,-58,-57,-56,-56,-55,-54,-53,-52,-51,-50,-49,-48,-47,-46,
102 	-45,-44,-43,-42,-41,-39,-38,-37,-36,-34,-33,-32,-30,-29,-27,-26,
103 	-24,-23,-22,-20,-19,-17,-16,-14,-12,-11, -9, -8, -6, -5, -3, -2
104 };
105 
106 #define MAXNOTES (16*12)
107 #define LINEAR_PERIOD_MAX (MAXNOTES*16*4)
108 
109 const mp_uword PlayerIT::lintab[769] = {
110 	16726,16741,16756,16771,16786,16801,16816,16832,16847,16862,16877,16892,16908,16923,16938,16953,
111 	16969,16984,16999,17015,17030,17046,17061,17076,17092,17107,17123,17138,17154,17169,17185,17200,
112 	17216,17231,17247,17262,17278,17293,17309,17325,17340,17356,17372,17387,17403,17419,17435,17450,
113 	17466,17482,17498,17513,17529,17545,17561,17577,17593,17608,17624,17640,17656,17672,17688,17704,
114 	17720,17736,17752,17768,17784,17800,17816,17832,17848,17865,17881,17897,17913,17929,17945,17962,
115 	17978,17994,18010,18027,18043,18059,18075,18092,18108,18124,18141,18157,18174,18190,18206,18223,
116 	18239,18256,18272,18289,18305,18322,18338,18355,18372,18388,18405,18421,18438,18455,18471,18488,
117 	18505,18521,18538,18555,18572,18588,18605,18622,18639,18656,18672,18689,18706,18723,18740,18757,
118 	18774,18791,18808,18825,18842,18859,18876,18893,18910,18927,18944,18961,18978,18995,19013,19030,
119 	19047,19064,19081,19099,19116,19133,19150,19168,19185,19202,19220,19237,19254,19272,19289,19306,
120 	19324,19341,19359,19376,19394,19411,19429,19446,19464,19482,19499,19517,19534,19552,19570,19587,
121 	19605,19623,19640,19658,19676,19694,19711,19729,19747,19765,19783,19801,19819,19836,19854,19872,
122 	19890,19908,19926,19944,19962,19980,19998,20016,20034,20052,20071,20089,20107,20125,20143,20161,
123 	20179,20198,20216,20234,20252,20271,20289,20307,20326,20344,20362,20381,20399,20418,20436,20455,
124 	20473,20492,20510,20529,20547,20566,20584,20603,20621,20640,20659,20677,20696,20715,20733,20752,
125 	20771,20790,20808,20827,20846,20865,20884,20902,20921,20940,20959,20978,20997,21016,21035,21054,
126 	21073,21092,21111,21130,21149,21168,21187,21206,21226,21245,21264,21283,21302,21322,21341,21360,
127 	21379,21399,21418,21437,21457,21476,21496,21515,21534,21554,21573,21593,21612,21632,21651,21671,
128 	21690,21710,21730,21749,21769,21789,21808,21828,21848,21867,21887,21907,21927,21946,21966,21986,
129 	22006,22026,22046,22066,22086,22105,22125,22145,22165,22185,22205,22226,22246,22266,22286,22306,
130 	22326,22346,22366,22387,22407,22427,22447,22468,22488,22508,22528,22549,22569,22590,22610,22630,
131 	22651,22671,22692,22712,22733,22753,22774,22794,22815,22836,22856,22877,22897,22918,22939,22960,
132 	22980,23001,23022,23043,23063,23084,23105,23126,23147,23168,23189,23210,23230,23251,23272,23293,
133 	23315,23336,23357,23378,23399,23420,23441,23462,23483,23505,23526,23547,23568,23590,23611,23632,
134 	23654,23675,23696,23718,23739,23761,23782,23804,23825,23847,23868,23890,23911,23933,23954,23976,
135 	23998,24019,24041,24063,24084,24106,24128,24150,24172,24193,24215,24237,24259,24281,24303,24325,
136 	24347,24369,24391,24413,24435,24457,24479,24501,24523,24545,24567,24590,24612,24634,24656,24679,
137 	24701,24723,24746,24768,24790,24813,24835,24857,24880,24902,24925,24947,24970,24992,25015,25038,
138 	25060,25083,25105,25128,25151,25174,25196,25219,25242,25265,25287,25310,25333,25356,25379,25402,
139 	25425,25448,25471,25494,25517,25540,25563,25586,25609,25632,25655,25678,25702,25725,25748,25771,
140 	25795,25818,25841,25864,25888,25911,25935,25958,25981,26005,26028,26052,26075,26099,26123,26146,
141 	26170,26193,26217,26241,26264,26288,26312,26336,26359,26383,26407,26431,26455,26479,26502,26526,
142 	26550,26574,26598,26622,26646,26670,26695,26719,26743,26767,26791,26815,26839,26864,26888,26912,
143 	26937,26961,26985,27010,27034,27058,27083,27107,27132,27156,27181,27205,27230,27254,27279,27304,
144 	27328,27353,27378,27402,27427,27452,27477,27502,27526,27551,27576,27601,27626,27651,27676,27701,
145 	27726,27751,27776,27801,27826,27851,27876,27902,27927,27952,27977,28003,28028,28053,28078,28104,
146 	28129,28155,28180,28205,28231,28256,28282,28307,28333,28359,28384,28410,28435,28461,28487,28513,
147 	28538,28564,28590,28616,28642,28667,28693,28719,28745,28771,28797,28823,28849,28875,28901,28927,
148 	28953,28980,29006,29032,29058,29084,29111,29137,29163,29190,29216,29242,29269,29295,29322,29348,
149 	29375,29401,29428,29454,29481,29507,29534,29561,29587,29614,29641,29668,29694,29721,29748,29775,
150 	29802,29829,29856,29883,29910,29937,29964,29991,30018,30045,30072,30099,30126,30154,30181,30208,
151 	30235,30263,30290,30317,30345,30372,30400,30427,30454,30482,30509,30537,30565,30592,30620,30647,
152 	30675,30703,30731,30758,30786,30814,30842,30870,30897,30925,30953,30981,31009,31037,31065,31093,
153 	31121,31149,31178,31206,31234,31262,31290,31319,31347,31375,31403,31432,31460,31489,31517,31546,
154 	31574,31602,31631,31660,31688,31717,31745,31774,31803,31832,31860,31889,31918,31947,31975,32004,
155 	32033,32062,32091,32120,32149,32178,32207,32236,32265,32295,32324,32353,32382,32411,32441,32470,
156 	32499,32529,32558,32587,32617,32646,32676,32705,32735,32764,32794,32823,32853,32883,32912,32942,
157 	32972,33002,33031,33061,33091,33121,33151,33181,33211,33241,33271,33301,33331,33361,33391,33421,
158 	33451 // one more value because of linear interpolation
159 };
160 
161 #define LOGFAC 2*16
162 
163 const mp_uint32 PlayerIT::logtab[] = {
164 	LOGFAC*907,LOGFAC*900,LOGFAC*894,LOGFAC*887,LOGFAC*881,LOGFAC*875,LOGFAC*868,LOGFAC*862,
165 	LOGFAC*856,LOGFAC*850,LOGFAC*844,LOGFAC*838,LOGFAC*832,LOGFAC*826,LOGFAC*820,LOGFAC*814,
166 	LOGFAC*808,LOGFAC*802,LOGFAC*796,LOGFAC*791,LOGFAC*785,LOGFAC*779,LOGFAC*774,LOGFAC*768,
167 	LOGFAC*762,LOGFAC*757,LOGFAC*752,LOGFAC*746,LOGFAC*741,LOGFAC*736,LOGFAC*730,LOGFAC*725,
168 	LOGFAC*720,LOGFAC*715,LOGFAC*709,LOGFAC*704,LOGFAC*699,LOGFAC*694,LOGFAC*689,LOGFAC*684,
169 	LOGFAC*678,LOGFAC*675,LOGFAC*670,LOGFAC*665,LOGFAC*660,LOGFAC*655,LOGFAC*651,LOGFAC*646,
170 	LOGFAC*640,LOGFAC*636,LOGFAC*632,LOGFAC*628,LOGFAC*623,LOGFAC*619,LOGFAC*614,LOGFAC*610,
171 	LOGFAC*604,LOGFAC*601,LOGFAC*597,LOGFAC*592,LOGFAC*588,LOGFAC*584,LOGFAC*580,LOGFAC*575,
172 	LOGFAC*570,LOGFAC*567,LOGFAC*563,LOGFAC*559,LOGFAC*555,LOGFAC*551,LOGFAC*547,LOGFAC*543,
173 	LOGFAC*538,LOGFAC*535,LOGFAC*532,LOGFAC*528,LOGFAC*524,LOGFAC*520,LOGFAC*516,LOGFAC*513,
174 	LOGFAC*508,LOGFAC*505,LOGFAC*502,LOGFAC*498,LOGFAC*494,LOGFAC*491,LOGFAC*487,LOGFAC*484,
175 	LOGFAC*480,LOGFAC*477,LOGFAC*474,LOGFAC*470,LOGFAC*467,LOGFAC*463,LOGFAC*460,LOGFAC*457,
176 	LOGFAC*453,LOGFAC*450,LOGFAC*447,LOGFAC*443,LOGFAC*440,LOGFAC*437,LOGFAC*434,LOGFAC*431,
177 	LOGFAC*428 // one more value because of linear interpolation
178 };
179 
180 // 2^(SlideValue/768) in 16.16 fixed point
181 // SlideValue in [-256..256]
182 const mp_uint32 PlayerIT::powtab[] = {
183 	52015, 52062, 52109, 52156, 52204, 52251, 52298, 52345, 52392, 52440, 52487, 52534, 52582, 52629, 52677, 52724,
184 	52772, 52820, 52867, 52915, 52963, 53011, 53059, 53107, 53154, 53202, 53250, 53299, 53347, 53395, 53443, 53491,
185 	53540, 53588, 53636, 53685, 53733, 53782, 53830, 53879, 53928, 53976, 54025, 54074, 54123, 54172, 54220, 54269,
186 	54318, 54367, 54417, 54466, 54515, 54564, 54613, 54663, 54712, 54761, 54811, 54860, 54910, 54959, 55009, 55059,
187 	55108, 55158, 55208, 55258, 55308, 55358, 55408, 55458, 55508, 55558, 55608, 55658, 55709, 55759, 55809, 55860,
188 	55910, 55961, 56011, 56062, 56112, 56163, 56214, 56264, 56315, 56366, 56417, 56468, 56519, 56570, 56621, 56672,
189 	56723, 56775, 56826, 56877, 56928, 56980, 57031, 57083, 57134, 57186, 57238, 57289, 57341, 57393, 57445, 57496,
190 	57548, 57600, 57652, 57704, 57757, 57809, 57861, 57913, 57965, 58018, 58070, 58123, 58175, 58228, 58280, 58333,
191 	58385, 58438, 58491, 58544, 58597, 58650, 58702, 58755, 58809, 58862, 58915, 58968, 59021, 59075, 59128, 59181,
192 	59235, 59288, 59342, 59395, 59449, 59503, 59556, 59610, 59664, 59718, 59772, 59826, 59880, 59934, 59988, 60042,
193 	60096, 60151, 60205, 60259, 60314, 60368, 60423, 60477, 60532, 60586, 60641, 60696, 60751, 60806, 60860, 60915,
194 	60970, 61025, 61081, 61136, 61191, 61246, 61301, 61357, 61412, 61468, 61523, 61579, 61634, 61690, 61746, 61801,
195 	61857, 61913, 61969, 62025, 62081, 62137, 62193, 62249, 62305, 62362, 62418, 62474, 62531, 62587, 62644, 62700,
196 	62757, 62814, 62870, 62927, 62984, 63041, 63098, 63155, 63212, 63269, 63326, 63383, 63440, 63498, 63555, 63612,
197 	63670, 63727, 63785, 63842, 63900, 63958, 64016, 64073, 64131, 64189, 64247, 64305, 64363, 64421, 64479, 64538,
198 	64596, 64654, 64713, 64771, 64830, 64888, 64947, 65005, 65064, 65123, 65182, 65240, 65299, 65358, 65417, 65476,
199 	65536, 65595, 65654, 65713, 65773, 65832, 65891, 65951, 66010, 66070, 66130, 66189, 66249, 66309, 66369, 66429,
200 	66489, 66549, 66609, 66669, 66729, 66789, 66850, 66910, 66971, 67031, 67092, 67152, 67213, 67273, 67334, 67395,
201 	67456, 67517, 67578, 67639, 67700, 67761, 67822, 67883, 67945, 68006, 68067, 68129, 68190, 68252, 68314, 68375,
202 	68437, 68499, 68561, 68623, 68685, 68747, 68809, 68871, 68933, 68995, 69057, 69120, 69182, 69245, 69307, 69370,
203 	69432, 69495, 69558, 69621, 69684, 69747, 69809, 69873, 69936, 69999, 70062, 70125, 70189, 70252, 70315, 70379,
204 	70442, 70506, 70570, 70633, 70697, 70761, 70825, 70889, 70953, 71017, 71081, 71145, 71209, 71274, 71338, 71403,
205 	71467, 71532, 71596, 71661, 71725, 71790, 71855, 71920, 71985, 72050, 72115, 72180, 72245, 72310, 72376, 72441,
206 	72507, 72572, 72638, 72703, 72769, 72834, 72900, 72966, 73032, 73098, 73164, 73230, 73296, 73362, 73429, 73495,
207 	73561, 73628, 73694, 73761, 73827, 73894, 73961, 74027, 74094, 74161, 74228, 74295, 74362, 74429, 74497, 74564,
208 	74631, 74699, 74766, 74833, 74901, 74969, 75036, 75104, 75172, 75240, 75308, 75376, 75444, 75512, 75580, 75648,
209 	75717, 75785, 75853, 75922, 75991, 76059, 76128, 76197, 76265, 76334, 76403, 76472, 76541, 76610, 76679, 76749,
210 	76818, 76887, 76957, 77026, 77096, 77165, 77235, 77305, 77375, 77445, 77514, 77584, 77655, 77725, 77795, 77865,
211 	77935, 78006, 78076, 78147, 78217, 78288, 78359, 78429, 78500, 78571, 78642, 78713, 78784, 78855, 78926, 78998,
212 	79069, 79140, 79212, 79283, 79355, 79427, 79498, 79570, 79642, 79714, 79786, 79858, 79930, 80002, 80074, 80147,
213 	80219, 80292, 80364, 80437, 80509, 80582, 80655, 80727, 80800, 80873, 80946, 81019, 81093, 81166, 81239, 81312,
214 	81386, 81459, 81533, 81607, 81680, 81754, 81828, 81902, 81976, 82050, 82124, 82198, 82272, 82346, 82421, 82495,
215 	82570 // one more value because of linear interpolation
216 };
217 
interpolate(mp_sint32 eax,mp_sint32 ebx,mp_sint32 ecx,mp_sint32 edi,mp_sint32 esi)218 mp_sint32	PlayerIT::interpolate(mp_sint32 eax,mp_sint32 ebx,mp_sint32 ecx,mp_sint32 edi,mp_sint32 esi)
219 {
220 	if (ebx==ecx) return edi;
221 	mp_sint32 di = ((eax-ebx)*(esi-edi))/(ecx-ebx)+edi;
222 	return (mp_sint32)di;
223 }
224 
225 // This takes the period with 8 bit fractional part
getlinfreq(mp_sint32 per)226 mp_sint32	PlayerIT::getlinfreq(mp_sint32 per)
227 {
228 	if (per<0) per=0;
229 	if (per>LINEAR_PERIOD_MAX*256) per=LINEAR_PERIOD_MAX*256;
230 
231 	mp_sint32 t = (LINEAR_PERIOD_MAX*256-per)/(768*256);
232 	mp_sint32 r = myMod(LINEAR_PERIOD_MAX*256-per, 768*256);
233 
234 	// Linear interpolation seems to be wrong here
235 	/*mp_sint32 frac = r & 255;
236 
237 	mp_sint32 r1 = ((lintab[r>>8])<<t)>>5;
238 	mp_sint32 r2 = ((lintab[(r>>8)+1])<<t)>>5;
239 
240 	return ((255-frac)*r1 + frac*r2) >> 8;*/
241 
242 	return t >= 0 ? (((lintab[r>>8])<<t)>>5) : (((lintab[r>>8])>>(-t))>>5);
243 }
244 
245 // This takes the period with 8 bit fractional part
getlogfreq(mp_sint32 per)246 mp_sint32	PlayerIT::getlogfreq(mp_sint32 per)
247 {
248 	return fixeddiv(14317056, per)>>8;
249 }
250 
getlinperiod(mp_sint32 note,mp_sint32 relnote,mp_sint32 finetune)251 mp_sint32	PlayerIT::getlinperiod(mp_sint32 note,mp_sint32 relnote,mp_sint32 finetune)
252 {
253 	note+=relnote+(mp_sint32)module->header.relnote;
254 
255 	//if (note<1) note = 1;
256 	if (note>MAXNOTES) note = MAXNOTES;
257 
258 	// t=(24L*OCTAVE+2-note)*32L-(fine>>1);
259 
260 	return ((LINEAR_PERIOD_MAX-((note-1)*16*4)-(finetune/2)));
261 }
262 
getlogperiod(mp_sint32 note,mp_sint32 relnote,mp_sint32 finetune)263 mp_sint32	PlayerIT::getlogperiod(mp_sint32 note,mp_sint32 relnote,mp_sint32 finetune)
264 {
265 	note+=relnote+(mp_sint32)module->header.relnote;
266 
267 	//if (note<1) note = 1;
268 	if (note>MAXNOTES) note = MAXNOTES;
269 
270 	mp_sint32 ft = finetune;
271 	ft+=128;
272 	mp_sint32 octave = (note-1)/12;
273 	mp_sint32 n = myMod(note-1, 12)<<3;
274 	mp_sint32 pi = (ft>>4)+n;
275 	mp_sint32 v1 = logtab[pi];
276 	mp_sint32 v2 = logtab[pi+1];
277 	mp_sint32 t = (ft>>4)-8;
278 	//mp_sint32 t = (ft>>4);
279 	return octave >= 0 ? (interpolate(t,0,15,v1,v2)>>octave) : (interpolate(t,0,15,v1,v2)<<(-octave));
280 }
281 
282 
PlayerIT(mp_uint32 frequency)283 PlayerIT::PlayerIT(mp_uint32 frequency) :
284 	PlayerBase(frequency)
285 {
286 	chninfo		= NULL;
287 	vchninfo	= NULL;
288 	attick		= NULL;
289 	// fill in some default values, don't know if this is necessary
290 
291 	tickSpeed			= 6;				// our tickspeed
292 	bpm					= 125;				// BPM speed
293 	ticker				= tickSpeed-1;		// runs from 0 to tickspeed-1
294 	patternIndex		= 0;				// holds current pattern index
295 	numEffects			= 0;				// current number of effects
296 	numChannels			= 0;				// current number of channels
297 	numMaxVirChannels	= 256;				// maximum amount of virtual channels
298 
299 	//loopstart = execloop = loopcounter=0;
300 
301 	patDelay = false;
302 	patDelayCount = 0;
303 	haltFlag = false;
304 
305 	options[PlayModeOptionPanning8xx] = true;
306 	options[PlayModeOptionPanningE8x] = false;
307 	options[PlayModeOptionForcePTPitchLimit] = true;
308 }
309 
~PlayerIT()310 PlayerIT::~PlayerIT()
311 {
312 	freeMemory();
313 }
314 
315 #define MYMAX(a, b) (mp_sint32)((a) > (b) ? (a) : (b))
316 
timerHandler(mp_sint32 currentBeatPacket)317 void PlayerIT::timerHandler(mp_sint32 currentBeatPacket)
318 {
319 	PlayerBase::timerHandler(currentBeatPacket);
320 
321 	if (paused)
322 		return;
323 
324 	// get current maximum virtual channels
325 	mp_sint32 oldMaxVirChannels = curMaxVirChannels;
326 
327 	mp_int64 dummy = (mp_int64)BPMCounter;
328 	dummy+=(mp_int64)adder;
329 	BPMCounter=(mp_sint32)dummy;
330 
331 	// check overflow-carry
332 	if ((dummy>>32))
333 	{
334 		tickhandler();
335 	}
336 
337 	if (module->header.flags & XModule::MODULE_AMSENVELOPES)
338 		updateBPMIndependent();
339 
340 	// if the new maximum of virtual channels is greater than the old one
341 	// set it to the new one, else keep the old one, because if some channels were
342 	// cut by stopSample() the mixer needs to shut these off
343 	setActiveChannels(MYMAX(curMaxVirChannels, oldMaxVirChannels));
344 }
345 
startPlaying(XModule * module,bool repeat,mp_uint32 startPosition,mp_uint32 startRow,mp_sint32 numChannels,const mp_ubyte * customPanningTable,bool idle,mp_sint32 patternIndex,bool playOneRowOnly)346 mp_sint32 PlayerIT::startPlaying(XModule* module,
347 								 bool repeat/* = false*/,
348 								 mp_uint32 startPosition/* = 0*/,
349 								 mp_uint32 startRow/* = 0*/,
350 								 mp_sint32 numChannels/* = -1*/,
351 								 const mp_ubyte* customPanningTable/* = NULL*/,
352 								 bool idle/* = false*/,
353 								 mp_sint32 patternIndex/* = -1*/,
354 								 bool playOneRowOnly/* = false*/)
355 {
356 
357 	/*for (mp_sint32 vmd = -256; vmd < 257; vmd++)
358 	{
359 		double fac = pow(2.0, vmd/768.0);
360 		printf("%d, ", (mp_sint32)(fac * 65536.0));
361 	}*/
362 
363 	numModuleChannels = module->header.channum;
364 	numVirtualChannels = numMaxVirChannels < numModuleChannels ? numModuleChannels : numMaxVirChannels;
365 
366 	return PlayerBase::startPlaying(module,
367 									repeat,
368 									startPosition,
369 									startRow,
370 									numVirtualChannels,
371 									customPanningTable,
372 									idle,
373 									patternIndex,
374 									playOneRowOnly);
375 }
376 
377 
restart(mp_uint32 startPosition,mp_uint32 startRow,bool resetMixer,const mp_ubyte * customPanningTable,bool playOneRowOnly)378 void PlayerIT::restart(mp_uint32 startPosition/* = 0*/, mp_uint32 startRow/* = 0*/, bool resetMixer/* = true*/, const mp_ubyte* customPanningTable/* = NULL*/, bool playOneRowOnly/* = false*/)
379 {
380 	if (chninfo == NULL)
381 		return;
382 
383 	bpm	= module->header.speed;
384 	tickSpeed = module->header.tempo;
385 	ticker = 0;
386 
387 	// after the speed has been assigned, it's time to call PlayerBase::restart
388 	PlayerBase::restart(startPosition, startRow, resetMixer, customPanningTable, playOneRowOnly);
389 
390 	this->adder = getbpmrate(this->bpm);
391 
392 	mp_sint32 i,j;
393 
394 	// clean up player specific variables
395 	patternIndex	= 0;
396 	numEffects		= 0;
397 	numChannels		= 0;
398 
399 	patDelay		= false;
400 	patDelayCount   = 0;
401 	haltFlag		= false;
402 
403 	startNextRow	= -1;
404 
405 	reset();
406 
407 	for (i = 0; i < numModuleChannels; i++)
408 	{
409 		chninfo[i].setMasterVol(0xff);
410 		chninfo[i].setPan(customPanningTable ? customPanningTable[i] : module->header.pan[i]);
411 	}
412 
413 	memset(rowHits, 0, sizeof(rowHits));
414 
415 	for (i = 0; i < (signed)startPosition; i++)
416 		for (j = 0; j < 256; j++)
417 			visitRow(i*256+j);
418 
419 	for (i = 0; i < (signed)startRow; i++)
420 		visitRow(startPosition*256+i);
421 }
422 
reset()423 void PlayerIT::reset()
424 {
425 	curMaxVirChannels = 0;
426 	memset(chninfo, 0, sizeof(TModuleChannel)*numModuleChannels);
427 	memset(vchninfo, 0, sizeof(TVirtualChannel)*numVirtualChannels);
428 	RESET_ALL_LOOPING
429 }
430 
resetAllSpeed()431 void PlayerIT::resetAllSpeed()
432 {
433 	bpm	= module->header.speed;
434 	tickSpeed = module->header.tempo;
435 	ticker = 0;
436 
437 	this->adder = getbpmrate(this->bpm);
438 }
439 
allocateStructures()440 mp_sint32 PlayerIT::allocateStructures()
441 {
442 	freeMemory();
443 
444 	chninfo			= new TModuleChannel[numModuleChannels];
445 	vchninfo		= new TVirtualChannel[numVirtualChannels];
446 	attick			= new mp_ubyte[numModuleChannels];
447 	return MP_OK;
448 }
449 
freeMemory()450 void PlayerIT::freeMemory()
451 {
452 	if (chninfo)
453 	{
454 		delete[] chninfo;
455 		chninfo = NULL;
456 	}
457 	if (vchninfo) \
458 	{
459 		delete[] vchninfo;
460 		vchninfo = NULL;
461 	}
462 	if (attick)
463 	{
464 		delete[] attick;
465 		attick = NULL;
466 	}
467 }
468 
469 ///////////////////////////////////////////////////////////////////////////////////
470 //					 controlling current song position                           //
471 ///////////////////////////////////////////////////////////////////////////////////
clearEffectMemory()472 void PlayerIT::clearEffectMemory()
473 {
474 	if (!module || !chninfo)
475 		return;
476 
477 	ticker = 0;
478 
479 	//loopstart = execloop = loopcounter=0;
480 	mp_sint32 i;
481 	for (i = 0; i < numModuleChannels; i++)
482 	{
483 		TModuleChannel *chnInf = &chninfo[i];
484 		RESETLOOPING
485 	}
486 
487 	patDelay = false;
488 	patDelayCount = 0;
489 	haltFlag = false;
490 
491 	startNextRow = -1;
492 
493 	memset(rowHits, 0, sizeof(rowHits));
494 
495 	for (i = 0; i < poscnt; i++)
496 		for (mp_sint32 j = 0; j < 256; j++)
497 			visitRow(i*256+j);
498 
499 	for (i = 0; i < (signed)rowcnt; i++)
500 		visitRow(poscnt*256+i);
501 }
502 
allocateVirtualChannel()503 PlayerIT::TVirtualChannel* PlayerIT::allocateVirtualChannel()
504 {
505 	const mp_sint32 numVirtualChannels = this->numVirtualChannels;
506 
507 	mp_sint32 i;
508 
509 	TVirtualChannel* vchn = vchninfo;
510 	for (i = 0; i < numVirtualChannels; i++, vchn++)
511 	{
512 		if (vchn->getBackground())
513 		{
514 			if (!vchn->getActive())
515 			{
516 				if (i+1 > curMaxVirChannels)
517 					curMaxVirChannels = i+1;
518 				vchn->setChannelIndex(i);
519 				return vchn;
520 			}
521 		}
522 	}
523 
524 	mp_sint32 chnIndex = -1;
525 	mp_sint32 vol = 0x7FFFFFFF;
526 	vchn = vchninfo;
527 	for (i = 0; i < curMaxVirChannels; i++, vchn++)
528 	{
529 		if (vchn->getBackground())
530 		{
531 			mp_sint32 newVol = vchn->getResultingVolume();
532 			if (newVol < vol)
533 			{
534 				vol = newVol;
535 				chnIndex = i;
536 			}
537 		}
538 	}
539 
540 	if (chnIndex != -1)
541 	{
542 		vchn = vchninfo + chnIndex;
543 		vchn->setChannelIndex(chnIndex);
544 		return vchn;
545 	}
546 
547 	return NULL;
548 }
549 
handleNoteOFF(TChnState & state)550 void PlayerIT::handleNoteOFF(TChnState& state)
551 {
552 	const mp_sint32 ins = state.getIns();
553 	if (ins && ins <= module->header.insnum)
554 	{
555 		// IT style fadeout also works without active envelope
556 		if (module->instr[ins-1].flags & TXMInstrument::IF_ITFADEOUT)
557 		{
558 			if (state.getVenv().envstruc!=NULL)
559 			{
560 				// envelope is off or on and looping
561 				if (!state.getVenv().isEnabled() ||
562 					(state.getVenv().isEnabled() && (state.getVenv().envstruc->type&4)))
563 				{
564 					state.setFadeout(true);
565 				}
566 			}
567 			// no envelope at all
568 			else
569 			{
570 				state.setFadeout(true);
571 			}
572 		}
573 		// XM style (envelope is off)
574 		else if (!state.getVenv().isEnabled())
575 		{
576 			state.setVol(0);
577 			state.adjustTremoloTremorVol();
578 		}
579 	}
580 
581 	state.setKeyon(false);
582 }
583 
handlePastNoteAction(TModuleChannel * chnInf,mp_ubyte pastNoteActionType)584 void PlayerIT::handlePastNoteAction(TModuleChannel* chnInf, mp_ubyte pastNoteActionType)
585 {
586 	TVirtualChannel* vchn = vchninfo;
587 	const mp_sint32 curMaxVirChannels = this->curMaxVirChannels;
588 
589 	switch (pastNoteActionType)
590 	{
591 		case 0:
592 		{
593 			for (mp_sint32 i = 0; i < curMaxVirChannels; i++, vchn++)
594 				if (vchn->getActive() && (vchn->getOldHost() == chnInf))
595 				{
596 					mp_sint32 index = vchn->getChannelIndex();
597 					stopSample(index);
598 					releaseVirtualChannel(vchn);
599 				}
600 			break;
601 		}
602 
603 		case 1:
604 		{
605 			for (mp_sint32 i = 0; i < curMaxVirChannels; i++, vchn++)
606 				if (vchn->getActive() && (vchn->getOldHost() == chnInf))
607 					handleNoteOFF(vchn->getRealState());
608 			break;
609 		}
610 
611 		case 2:
612 		{
613 			for (mp_sint32 i = 0; i < curMaxVirChannels; i++, vchn++)
614 				if (vchn->getActive() && (vchn->getOldHost() == chnInf))
615 					vchn->getRealState().setFadeout(true);
616 			break;
617 		}
618 	}
619 }
620 
handleDCT(TModuleChannel * chnInf,const TNNATriggerInfo & triggerInfo,mp_ubyte DCT,mp_ubyte DCA)621 bool PlayerIT::handleDCT(TModuleChannel* chnInf, const TNNATriggerInfo& triggerInfo, mp_ubyte DCT, mp_ubyte DCA)
622 {
623 	TVirtualChannel* vchn = vchninfo;
624 	const mp_sint32 curMaxVirChannels = this->curMaxVirChannels;
625 	for (mp_sint32 i = 0; i < curMaxVirChannels; i++, vchn++)
626 	{
627 		if (vchn->getActive() && (vchn->getOldHost() == chnInf || vchn->getHost() == chnInf))
628 		{
629 			bool matchDCT;
630 
631 			// normal case (instrument supplied with note)
632 			if (triggerInfo.ins)
633 			{
634 				// must always be the same instrument
635 				matchDCT = (vchn->getIns() == triggerInfo.ins);
636 				// check for note
637 				if (DCT == 1)
638 					matchDCT &= (vchn->getNote() == triggerInfo.note);
639 				// check for sample
640 				else if (DCT == 2)
641 					matchDCT &= (vchn->getSmp() == triggerInfo.smp);
642 			}
643 			// no instrument supplied with note
644 			else
645 			{
646 				matchDCT = true;
647 				// note check doesn't do anything if instrument is 0
648 				if (DCT == 1)
649 					continue;
650 			}
651 
652 			if (!matchDCT)
653 				continue;
654 
655 			// cut = keep channel
656 			if (DCA == 0)
657 			{
658 				mp_sint32 index = vchn->getChannelIndex();
659 				stopSample(index);
660 				releaseVirtualChannel(vchn);
661 			}
662 			// note off
663 			else if (DCA == 1)
664 			{
665 				// virtual channel is no longer linked to host
666 				if (vchn->getOldHost() == chnInf)
667 					handleNoteOFF(vchn->getRealState());
668 				// virtual channel is linked to host, unlink and handle note off
669 				else
670 				{
671 					// important: first set host to NULL
672 					// THEN set key on flag
673 					TVirtualChannel* oldvchn = chnInf->unlinkVchn();
674 					handleNoteOFF(oldvchn->getRealState());
675 				}
676 			}
677 			// note fade
678 			else if (DCA == 2)
679 			{
680 				// virtual channel is no longer linked to host
681 				if (vchn->getOldHost() == chnInf)
682 					vchn->getRealState().setFadeout(true);
683 				// virtual channel is linked to host, unlink and handle fade out
684 				else
685 				{
686 					// important: first set host to NULL
687 					// THEN set fade out
688 					chnInf->unlinkVchn()->setFadeout(true);
689 				}
690 			}
691 		}
692 	}
693 
694 	// deal with no instrument case
695 	if (!triggerInfo.ins)
696 	{
697 		// if DCT is set to note, just continue with playing the note
698 		if (DCT == 1)
699 			return true;
700 		// if DCT is set to ins/smp and DCA is set to cut, cut and don't play the current note
701 		else if (DCA == 0)
702 			return false;
703 	}
704 
705 	return true;
706 }
707 
handleNNAs(TModuleChannel * chnInf,const TNNATriggerInfo & triggerInfo)708 bool PlayerIT::handleNNAs(TModuleChannel* chnInf, const TNNATriggerInfo& triggerInfo)
709 {
710 	/*if (poscnt == 7 && rowcnt == 00)
711 	{
712 		int i=0;
713 		i++;
714 		i--;
715 	}*/
716 
717 	// sanity checks
718 	if (triggerInfo.ins > module->header.insnum  ||
719 		!triggerInfo.note ||
720 		triggerInfo.smp < 0)
721 		return true;
722 
723 	TVirtualChannel* newVchn = allocateVirtualChannel();
724 	if (newVchn == NULL)
725 		return false;
726 
727 	mp_uword insflags = chnInf->getInsflags();
728 	mp_ubyte NNA = (insflags>>4) & 3;
729 	mp_ubyte DCT = (insflags>>6) & 3;
730 	mp_ubyte DCA = (insflags>>8) & 3;
731 
732 	if (DCT)
733 	{
734 		if (!handleDCT(chnInf, triggerInfo, DCT, DCA))
735 			return false;
736 	}
737 
738 	// do we have some virtual channel already?
739 	if (chnInf->hasVchn())
740 	{
741 		// NNA = CUT? Use the same virtual channel for playback
742 		if (NNA == 0)
743 			return true;
744 		// NNA = continue
745 		else if (NNA == 1)
746 		{
747 			chnInf->unlinkVchn();
748 			chnInf->linkVchn(newVchn);
749 			return true;
750 		}
751 		// NNA = note off
752 		else if (NNA == 2)
753 		{
754 			// important: first set host to NULL
755 			// THEN set key on flag
756 			TVirtualChannel* oldvchn = chnInf->unlinkVchn();
757 			handleNoteOFF(oldvchn->getRealState());
758 			chnInf->linkVchn(newVchn);
759 			return true;
760 		}
761 		// NNA = note fade
762 		else if (NNA == 3)
763 		{
764 			// important: first set host to NULL
765 			// THEN set fade out
766 			chnInf->unlinkVchn()->setFadeout(true);
767 			chnInf->linkVchn(newVchn);
768 			return true;
769 		}
770 	}
771 	else
772 	{
773 		chnInf->linkVchn(newVchn);
774 	}
775 
776 	return true;
777 }
778 
adjustVirtualChannels()779 void PlayerIT::adjustVirtualChannels()
780 {
781 	mp_sint32 i;
782 
783 	TVirtualChannel* vchn = vchninfo;
784 	for (i = 0; i < curMaxVirChannels; i++, vchn++)
785 	{
786 		if (!vchn->getActive())
787 			continue;
788 
789 		if (vchn->getBackground())
790 		{
791 			if (!isChannelPlaying(i) ||
792 				!vchn->getVol() ||
793 				!vchn->getMasterVol() ||
794 				!vchn->getFadevolstart() ||
795 				vchn->getVenv().cutted(vchn->getKeyon()))
796 			{
797 				//bool cutted = vchn->getVenv().cutted(vchn->getKeyon());
798 				mp_sint32 index = vchn->getChannelIndex();
799 				stopSample(index);
800 				releaseVirtualChannel(vchn);
801 				continue;
802 			}
803 		}
804 		/*else
805 		{
806 			if (!vchn->getFadevolstart() ||
807 				vchn->getVenv().cutted(vchn->getKeyon()))
808 			{
809 				mp_sint32 index = vchn->getChannelIndex();
810 				stopSample(index);
811 				continue;
812 			}
813 		}*/
814 	}
815 }
816 
prenvelope(TPrEnv * env,bool keyon,bool timingIT)817 void PlayerIT::prenvelope(TPrEnv *env, bool keyon, bool timingIT)
818 {
819 	if (env->isEnabled())
820 	{
821 		// if we're sitting on a sustain point and key is on, we don't advance further
822 		if ((env->envstruc->type&2) && (env->a==env->envstruc->sustain) &&
823 			(env->step == env->envstruc->env[env->a][0]) && keyon)
824 			return;
825 
826 		// IT-style envelopes count differently
827 		if (timingIT)
828 		{
829 			if ((env->step<=env->envstruc->env[env->b][0]) && (env->b < env->envstruc->num))
830 				env->step++;
831 
832 			if (env->step > env->envstruc->env[env->b][0]) {
833 
834 				// normal loop
835 				if ((env->envstruc->type&4))
836 				{
837 					// check for envelope loop break (AMS)
838 					if ((!(env->envstruc->type&8) || keyon) &&
839 						!(!keyon && (env->envstruc->type&2) && env->envstruc->sustain == env->envstruc->loope)) // Break envelope if sustain pt == loop end point AND sustain is enabled AND key off is send
840 					{
841 						if (env->b==env->envstruc->loope) {
842 							env->a=env->envstruc->loops;
843 							env->b=env->envstruc->loops+1;
844 							env->step=env->envstruc->env[env->a][0];
845 							return;
846 						}
847 					}
848 				}
849 
850 				// sustain loop (IT)
851 				if ((env->envstruc->type&16))
852 				{
853 					if (keyon)
854 					{
855 						if (env->b==env->envstruc->susloope) {
856 							env->a=env->envstruc->sustain;
857 							env->b=env->envstruc->sustain+1;
858 							env->step=env->envstruc->env[env->a][0];
859 							return;
860 						}
861 					}
862 				}
863 
864 				// Increase envelope position if there are more points to come
865 				if (env->b < env->envstruc->num - 1) {
866 					env->a++;
867 					env->b++;
868 				}
869 				//else
870 				//{
871 				//	// fuck you
872 				//	printf("fuck");
873 				//}
874 			}
875 
876 		}
877 		else
878 		{
879 			if ((env->step!=env->envstruc->env[env->b][0]) && (env->b < env->envstruc->num))
880 				env->step++;
881 
882 			if (env->step == env->envstruc->env[env->b][0]) {
883 
884 				// normal loop
885 				if ((env->envstruc->type&4))
886 				{
887 					// check for envelope loop break (AMS)
888 					if ((!(env->envstruc->type&8) || keyon) &&
889 						!(!keyon && (env->envstruc->type&2) && env->envstruc->sustain == env->envstruc->loope)) // Break envelope if sustain pt == loop end point AND sustain is enabled AND key off is send
890 					{
891 						if (env->b==env->envstruc->loope) {
892 							env->a=env->envstruc->loops;
893 							env->b=env->envstruc->loops+1;
894 							env->step=env->envstruc->env[env->a][0];
895 							return;
896 						}
897 					}
898 				}
899 
900 				// sustain loop (IT)
901 				if ((env->envstruc->type&16))
902 				{
903 					if (keyon) // Break envelope if sustain pt == loop end point AND sustain is enabled AND key off is send
904 					{
905 						if (env->b==env->envstruc->susloope) {
906 							env->a=env->envstruc->sustain;
907 							env->b=env->envstruc->sustain+1;
908 							env->step=env->envstruc->env[env->a][0];
909 							return;
910 						}
911 					}
912 				}
913 
914 				// Increase envelope position if there are more points to come
915 				if (env->b < env->envstruc->num - 1) {
916 					env->a++;
917 					env->b++;
918 				}
919 			}
920 		}
921 	}
922 
923 }
924 
getenvval(TPrEnv * env,mp_sint32 n)925 mp_sint32 PlayerIT::getenvval(TPrEnv *env,mp_sint32 n)
926 {
927 	if (env->isEnabled())
928 	{
929 		mp_sint32 step = env->step;
930 		if (step > env->envstruc->env[env->b][0])
931 			step = env->envstruc->env[env->b][0];
932 		mp_sint32 dx = (env->envstruc->env[env->b][0]-env->envstruc->env[env->a][0]);
933 		if (dx==0) dx=1;
934 		mp_sint32 t = (env->envstruc->env[env->b][0]-step)*65536/dx;
935 		mp_sint32 y0 = env->envstruc->env[env->a][1];
936 		mp_sint32 y1 = env->envstruc->env[env->b][1];
937 
938 		mp_sint32 y = (y0*t)+(y1*(65536-t));
939 
940 		return y>>16;
941 	}
942 	return n;
943 }
944 
getFinalPeriod(TChnState & state,mp_sint32 p)945 mp_sint32 PlayerIT::getFinalPeriod(TChnState& state, mp_sint32 p)
946 {
947 	mp_sint32 envVib = 0;
948 	p<<=8;
949 
950 	if (state.vibenv.isEnabled())
951 	{
952 		mp_sint32 eval = (getenvval(&state.vibenv,128)-128) << (state.vibenv.envstruc->type>>6);
953 		// AMS doc says vibrato with amplify set to 8 equals vibrato 0xF
954 		// => alright
955 		envVib = (eval*61408)>>(3+16-8);
956 	}
957 
958 	if (state.avibused & 127)
959 	{
960 		// if this is XM style auto vibrato, the running counter is divided by 4
961 		mp_ubyte vp = state.avibcnt >> ((state.avibused & 128) ? 0 : 2);
962 		mp_ubyte vd = state.avibdepth;
963 
964 		mp_sint32 vm = 0;
965 
966 		mp_sint32 vl = 0;
967 		switch (state.avibused & 127)
968 		{
969 			// sine
970 			case 1 : vl=vibtab[vp&31]; break;
971 			// square
972 			case 2 : vl=255; break;
973 			// ramp down
974 			case 3 : {
975 						vl=((vp&31)*539087)>>16;
976 						if ((vp&63)>31) vl=255-vl;
977 						vl=-vl;
978 					 }; break;
979 			// ramp up
980 			case 4 : {
981 						vl=((vp&31)*539087)>>16;
982 						if ((vp&63)>31) vl=255-vl;
983 					 }; break;
984 		}
985 
986 		// IT style vibrato sweep
987 		if (state.avibused & 128)
988 		{
989 			if (state.avibsweep && state.avibswcnt < (vd << 8))
990 				vm = (vl*state.avibswcnt)>>(1+8);
991 			else
992 				vm = (vl*vd)>>1;
993 		}
994 		// XM style vibrato sweep
995 		else
996 		{
997 			vm = (vl*vd)>>1;
998 
999 			if (state.avibsweep)
1000 			{
1001 				vm*=(mp_sint32)state.avibswcnt * 256;
1002 				vm/=state.avibsweep;
1003 				vm>>=8;
1004 			}
1005 		}
1006 
1007 		if ((vp&63)>31) vm=-vm;
1008 
1009 		// IT style envelope and amiga periods?
1010 		if (!(module->header.freqtab&1) && (state.avibused & 128))
1011 		{
1012 			// vibrato value has 8 bit fractional part
1013 			mp_uint32 vmi = vm >> 8;
1014 			// convert fraction to 16 bit
1015 			mp_uint32 vmf = (vm & 255) << 8;
1016 
1017 			// table ranges from [-256..256]
1018 			// elevate index to start by 0
1019 			mp_uint32 fac1 = powtab[vmi+256];
1020 			mp_uint32 fac2 = powtab[vmi+256+1];
1021 			// interpolate between two array values
1022 			mp_uint32 fac = fixedmul(65536-vmf, fac1) + fixedmul(vmf, fac2);
1023 
1024 			return (fixedmul(p<<8, fac)>>8) + envVib;
1025 
1026 			// see ITTECH.TXT
1027 			//double fac = pow(2.0, vm/(768.0*256.0));
1028 			//return (mp_sint32)(p*fac) + envVib;
1029 		}
1030 		// linear periods
1031 		return (p+vm+envVib);
1032 	}
1033 	else return (p+envVib);
1034 }
1035 
playInstrument(TModuleChannel * chnInf,bool bNoRestart)1036 void PlayerIT::playInstrument(TModuleChannel* chnInf, bool bNoRestart/* = false*/)
1037 {
1038 	const mp_sint32 ins = chnInf->getIns();
1039 	const mp_sint32 smp = chnInf->getSmp();
1040 	const mp_sint32 chn = chnInf->getPlaybackChannelIndex();
1041 
1042 	if (chn < 0 || !ins || ins > module->header.insnum)
1043 		return;
1044 
1045 	if (module->instr[ins-1].samp && smp != -1)
1046 	{
1047 		chnInf->resetFlag(CHANNEL_FLAGS_UPDATE_IGNORE);
1048 
1049 		const mp_sint32 i = smp;
1050 
1051 		// start out with the flags for 16bit sample
1052 		mp_sint32 flags = ((module->smp[i].type&16)>>4)<<2;
1053 		// add looping + backward flags
1054 		flags |= module->smp[i].type&(3+128);
1055 		// one shot forward looping?
1056 		flags |= module->smp[i].type & 32;
1057 
1058 		// force forward playing
1059 		if (chnInf->isFlagSet(CHANNEL_FLAGS_FORCE_FORWARD))
1060 			flags &= ~128;
1061 
1062 		// force backward playing
1063 		if (chnInf->isFlagSet(CHANNEL_FLAGS_FORCE_BACKWARD))
1064 			flags |= 128;
1065 
1066 		if (flags&3)
1067 		{
1068 			if (chnInf->isFlagSet(CHANNEL_FLAGS_FORCE_BILOOP))
1069 				flags = (flags & ~3) | 2;
1070 
1071 			// bNoRestart = false means play new sample from beginning or sample offset
1072 			if (!bNoRestart)
1073 			{
1074 				playSample(chn,
1075 						   (mp_sbyte*)module->smp[i].sample,
1076 						   module->smp[i].samplen,
1077 						   chnInf->smpoffs + chnInf->smpoffshigh,
1078 						   0, // sample offset fraction
1079 						   !playModeChopSampleOffset,
1080 						   module->smp[i].loopstart,
1081 						   module->smp[i].loopstart+module->smp[i].looplen,
1082 						   flags);
1083 			}
1084 			// bNoRestart = true means play new sample from beginning of the last sample
1085 			else
1086 			{
1087 				mp_sint32 smpoffset = chnInf->smpoffs ? (chnInf->smpoffs+chnInf->smpoffshigh) : getSamplePos(chn);
1088 				mp_sint32 smpoffsetfrac = chnInf->smpoffs ? 0 : getSamplePosFrac(chn);
1089 
1090 				playSample(chn,
1091 						   (mp_sbyte*)module->smp[i].sample,
1092 						   module->smp[i].samplen,
1093 						   smpoffset,
1094 						   smpoffsetfrac, // sample offset fraction
1095 						   true,
1096 						   module->smp[i].loopstart,
1097 						   module->smp[i].loopstart+module->smp[i].looplen,
1098 						   flags);
1099 			}
1100 		}
1101 		else
1102 		{
1103 
1104 			// bNoRestart = false means play new sample from beginning or sample offset
1105 			if (!bNoRestart)
1106 			{
1107 				playSample(chn,(mp_sbyte*)module->smp[i].sample,
1108 						   module->smp[i].samplen,
1109 						   chnInf->smpoffs + chnInf->smpoffshigh,
1110 						   0, // sample offset fraction
1111 						   !playModeChopSampleOffset,
1112 						   0,
1113 						   module->smp[i].samplen,
1114 						   flags);
1115 			}
1116 			// bNoRestart = true means play new sample from beginning of the last sample AND don't ramp volume up
1117 			else
1118 			{
1119 				mp_sint32 smpoffset = chnInf->smpoffs ? (chnInf->smpoffs+chnInf->smpoffshigh) : getSamplePos(chn);
1120 				mp_sint32 smpoffsetfrac = chnInf->smpoffs ? 0 : getSamplePosFrac(chn);
1121 
1122 				playSample(chn,(mp_sbyte*)module->smp[i].sample,
1123 						   module->smp[i].samplen,
1124 						   smpoffset,
1125 						   smpoffsetfrac, // sample offset fraction
1126 						   true,
1127 						   0,
1128 						   module->smp[i].samplen,
1129 						   flags);
1130 			}
1131 		}
1132 
1133 	}
1134 	else
1135 	{
1136 		stopSample(chn);
1137 	}
1138 }
1139 
updatePlayModeFlags()1140 void PlayerIT::updatePlayModeFlags()
1141 {
1142 	// the following flags are exclusive
1143 	newInsPTFlag = (module->header.flags & XModule::MODULE_PTNEWINSTRUMENT);
1144 	newInsST3Flag = (module->header.flags & XModule::MODULE_ST3NEWINSTRUMENT);
1145 	oldPTInsChangeFlag = (module->header.flags & XModule::MODULE_OLDPTINSTRUMENTCHANGE);
1146 
1147 	// 4-channel Protracker module = EXACT PTK replay should be applied
1148 	playModePT = ((module->header.flags & XModule::MODULE_PTNEWINSTRUMENT) && (module->header.channum == 4) && playMode == PlayMode_Auto) ||
1149 					   (playMode == PlayMode_ProTracker2) || (playMode == PlayMode_ProTracker3);
1150 
1151 	// This is a module with PTK limits
1152 	playModePTPitchLimit = ((module->header.flags & XModule::MODULE_PTNEWINSTRUMENT) && playMode == PlayMode_Auto) || (playMode == PlayMode_ProTracker2) || (playMode == PlayMode_ProTracker3);
1153 
1154 	// Override module playmode settings
1155 	switch (playMode)
1156 	{
1157 		case PlayMode_ProTracker2:
1158 			newInsPTFlag = true;
1159 			newInsST3Flag = false;
1160 			oldPTInsChangeFlag = true;
1161 			break;
1162 		case PlayMode_ProTracker3:
1163 			newInsPTFlag = true;
1164 			newInsST3Flag = false;
1165 			oldPTInsChangeFlag = false;
1166 			break;
1167 		case PlayMode_ScreamTracker3:
1168 		case PlayMode_ImpulseTracker:
1169 			newInsPTFlag = false;
1170 			newInsST3Flag = true;
1171 			oldPTInsChangeFlag = false;
1172 			break;
1173 		case PlayMode_FastTracker2:
1174 			newInsPTFlag = false;
1175 			newInsST3Flag = false;
1176 			oldPTInsChangeFlag = false;
1177 			break;
1178 		case PlayMode_Auto:
1179 			break;
1180 	}
1181 
1182 	playModeFT2 = (playMode == PlayMode_FastTracker2 ? true : false);
1183 	if (playMode == PlayMode_Auto && (module->header.flags & XModule::MODULE_XMARPEGGIO))
1184 		playModeFT2 = true;
1185 
1186 	// Chop off samples which sample offsets greater sample length?
1187 	playModeChopSampleOffset = playModeFT2 || (playMode == PlayMode_ProTracker3);
1188 }
1189 
calcVibrato(TModuleChannel * chnInf,mp_sint32 effcnt,mp_sint32 depthShift)1190 mp_sint32 PlayerIT::calcVibrato(TModuleChannel* chnInf, mp_sint32 effcnt, mp_sint32 depthShift/* = 5*/)
1191 {
1192 	mp_sint32 vp = chnInf->vibpos[effcnt];
1193 	mp_sint32 vd = chnInf->vibdepth[effcnt];
1194 
1195 	mp_sint32 vm = (vibtab[vp&31]*vd) >> ((module->header.flags & XModule::MODULE_ITNEWEFFECTS) ? (depthShift+1) : depthShift);
1196 	if ((vp&63)>31) vm=-vm;
1197 	return vm;
1198 }
1199 
doTickVolslidePT(TModuleChannel * chnInf,mp_sint32 effcnt)1200 void PlayerIT::doTickVolslidePT(TModuleChannel* chnInf, mp_sint32 effcnt)
1201 {
1202 	mp_ubyte x = chnInf->old[effcnt].volslide>>4;
1203 	mp_ubyte y = chnInf->old[effcnt].volslide&0xf;
1204 
1205 	// 08/31/04: fixed...
1206 	// don't reject volume slide if both operands are set
1207 	// instead, slide up
1208 	// see other volume slides as well
1209 	if (x&&y) y = 0;
1210 
1211 	if (ticker) {
1212 		if (x) {
1213 			chnInf->incVol(x*4);
1214 		}
1215 		if (y) {
1216 			chnInf->decVol(y*4);
1217 		}
1218 		chnInf->adjustTremoloTremorVol();
1219 	}
1220 }
1221 
doTickVolslideST(TModuleChannel * chnInf,mp_sint32 effcnt)1222 void PlayerIT::doTickVolslideST(TModuleChannel* chnInf, mp_sint32 effcnt)
1223 {
1224 	if (!(module->header.flags & XModule::MODULE_OLDS3MVOLSLIDES) &&
1225 		ticker == 0)
1226 		return;
1227 
1228 	mp_ubyte x = chnInf->old[effcnt].volslide>>4;
1229 	mp_ubyte y = chnInf->old[effcnt].volslide&0xf;
1230 
1231 	if (x == 0xF && y) return;
1232 	if (y == 0xF && x) return;
1233 
1234 	if (x && y) y = 0;
1235 
1236 	if (x) {
1237 		chnInf->incVol(x*4);
1238 	}
1239 	if (y) {
1240 		chnInf->decVol(y*4);
1241 	}
1242 	chnInf->adjustTremoloTremorVol();
1243 }
1244 
doTickEffect(TModuleChannel * chnInf,mp_sint32 effcnt)1245 void PlayerIT::doTickEffect(TModuleChannel* chnInf, mp_sint32 effcnt)
1246 {
1247 	const mp_sint32 chn = chnInf->getPlaybackChannelIndex();
1248 
1249 	mp_ubyte x,y;
1250 	mp_ubyte vp,vd;
1251 	mp_sint32 vm;
1252 
1253 	// IN PTK playmode, we've got a bunch of tick 0 effects
1254 	// which are repeated as long as the pattern delay applies
1255 	// ONLY valid for PTK playmode & effects, for other effects this leads to undefined results
1256 	if (playModePT)
1257 	{
1258 		if (patDelay && ticker &&
1259 			// Those effects are NOT executed
1260 			chnInf->eff[effcnt] > 0x09 &&
1261 			chnInf->eff[effcnt] != 0x33 &&
1262 			chnInf->eff[effcnt] != 0x34 &&
1263 			chnInf->eff[effcnt] != 0x35 &&
1264 			chnInf->eff[effcnt] != 0x36 &&
1265 			chnInf->eff[effcnt] != 0x37 &&
1266 			chnInf->eff[effcnt] != 0x38 &&
1267 			chnInf->eff[effcnt] < 0x3C)
1268 		{
1269 			if (!(ticker % tickSpeed))
1270 				doEffect(chnInf, effcnt);
1271 		}
1272 	}
1273 
1274 	switch (chnInf->eff[effcnt]) {
1275 		// portamento up
1276 		case 0x01:
1277 			if (ticker) {
1278 				chnInf->decPer(chnInf->old[effcnt].portaup*4);
1279 				handlePeriodUnderflow(chnInf);
1280 				chnInf->adjustVibratoPer();
1281 			}
1282 			break;
1283 
1284 		// portamento down
1285 		case 0x02:
1286 			if (ticker) {
1287 				chnInf->incPer(chnInf->old[effcnt].portadown*4);
1288 				handlePeriodOverflow(chnInf);
1289 				chnInf->adjustVibratoPer();
1290 			}
1291 			break;
1292 
1293 		// note portamento
1294 		case 0x03:
1295 		{
1296 			if (ticker&&chnInf->destnote) {
1297 				// If this is an XM module we need to store the last portamento operand always in the buffer for the second effect
1298 				mp_sint32 op = ((module->header.flags & XModule::MODULE_XMPORTANOTEBUFFER)  && numEffects == 2) ? chnInf->old[1].portanote : chnInf->old[effcnt].portanote;
1299 				chnInf->slideToPer(op*4);
1300 				chnInf->adjustVibratoPer();
1301 			}
1302 			break;
1303 		}
1304 
1305 		// vibrato (applying extra hacks for XM compatibility)
1306 		// In FT2 the vibrato contained in the volume column works a bit different
1307 		// than the vibrato in the effect column:
1308 		// After the vibrato has occured in the volumn column the pitch of the last
1309 		// vibrato calculation stays on until the next pitch effect occurs
1310 		case 0x04:
1311 		{
1312 			x = chnInf->eop[effcnt]>>4;
1313 			y = chnInf->eop[effcnt]&0xf;
1314 
1315 			mp_sint32 effNum = effcnt;
1316 			// in FT2 play mode the last vibrato
1317 			// value comes always from the effect column (index 1)
1318 			if ((module->header.flags & XModule::MODULE_XMPORTANOTEBUFFER)  && numEffects == 2)
1319 			{
1320 				effNum = 1;
1321 			}
1322 
1323 			if (x) chnInf->vibspeed[effNum]=x;
1324 			if (y) chnInf->vibdepth[effNum]=y;
1325 
1326 			mp_sint32 vmp = chnInf->getPer();
1327 
1328 			vm = calcVibrato(chnInf, effNum);
1329 
1330 			if (ticker || (module->header.flags & XModule::MODULE_ITNEWEFFECTS))
1331 				chnInf->vibpos[effNum]+=chnInf->vibspeed[effNum];
1332 
1333 			vmp+=vm;
1334 
1335 			mp_sint32 maxTicks = patDelay ? patDelayCount : tickSpeed;
1336 
1337 			// the vibrato in the volumn volumn (index 0) works differently
1338 			// before applying that, we assure that this is an XM module by checking
1339 			// the module header
1340 			if ((module->header.flags & XModule::MODULE_XMVOLCOLUMNVIBRATO) &&
1341 				ticker == maxTicks - 1)
1342 			{
1343 				if (!effcnt)
1344 					chnInf->setFinalVibratoPer(vmp);
1345 				else
1346 					chnInf->adjustVibratoPer();
1347 			}
1348 
1349 			if (chn >= 0)
1350 				setFreq(chn,getFinalFreq(chnInf->chnstat(),getFinalPeriod(chnInf->chnstat(),vmp)));
1351 			break;
1352 		}
1353 
1354 		// note porta + volume slide
1355 		case 0x05:
1356 		{
1357 			if (ticker&&chnInf->destnote) {
1358 				// If this is an XM module we need to store the last portamento operand always in the buffer for the second effect
1359 				mp_sint32 op = (module->header.flags & XModule::MODULE_XMPORTANOTEBUFFER) ? chnInf->old[1].portanote : chnInf->old[effcnt].portanote;
1360 				chnInf->slideToPer(op*4);
1361 				chnInf->adjustVibratoPer();
1362 			}
1363 
1364 			if (module->header.flags & XModule::MODULE_ST3DUALCOMMANDS)
1365 				doTickVolslideST(chnInf, effcnt);
1366 			else
1367 				doTickVolslidePT(chnInf, effcnt);
1368 			break;
1369 		}
1370 
1371 		// vibrato + volume slide
1372 		case 0x06:
1373 		{
1374 			vm = calcVibrato(chnInf, effcnt);
1375 
1376 			if (ticker)
1377 				chnInf->vibpos[effcnt]+=chnInf->vibspeed[effcnt];
1378 
1379 			if (chn >= 0)
1380 				setFreq(chn,getFinalFreq(chnInf->chnstat(),getFinalPeriod(chnInf->chnstat(),chnInf->getPer()+vm)));
1381 
1382 			if (module->header.flags & XModule::MODULE_ST3DUALCOMMANDS)
1383 				doTickVolslideST(chnInf, effcnt);
1384 			else
1385 				doTickVolslidePT(chnInf, effcnt);
1386 			break;
1387 		}
1388 
1389 		// tremolo, this is not the exact FT2 way. FT2 way doesn't make sense at all, fuck it
1390 		// (applying extra hacks for XM compatibility)
1391 		case 0x07:
1392 		{
1393 			x = chnInf->eop[effcnt]>>4;
1394 			y = chnInf->eop[effcnt]&0xf;
1395 			if (x) chnInf->trmspeed[effcnt]=x;
1396 			if (y) chnInf->trmdepth[effcnt]=y;
1397 
1398 			vp = chnInf->trmpos[effcnt];
1399 			vd = chnInf->trmdepth[effcnt];
1400 
1401 			mp_sint32 vmp = playModeFT2 ? (ticker == 0 ? chnInf->getVolume() : chnInf->getTremoloVol()) :
1402 				chnInf->getVolume();
1403 
1404 			// IT in new effects mode processes at non row tick
1405 			if (ticker || (module->header.flags & XModule::MODULE_ITNEWEFFECTS))
1406 			{
1407 				// IT in new effects mode is two times finer
1408 				vm = (vibtab[vp&31]*vd) >> ((module->header.flags & XModule::MODULE_ITNEWEFFECTS) ? (6-1) : (6-2));
1409 				if ((vp&63)>31) vm=-vm;
1410 				vmp+=vm;
1411 				if (vmp<0) vmp=0;
1412 				if (vmp>255) vmp=255;
1413 				chnInf->trmpos[effcnt]+=chnInf->trmspeed[effcnt];
1414 			}
1415 
1416 			// FT2 hack... final tremolo volume stays on
1417 			if (playModeFT2 && (ticker == tickSpeed - 1))
1418 			{
1419 				chnInf->setFinalTremVol(vmp);
1420 			}
1421 
1422 			if (chn >= 0)
1423 				setVol(chn, getFinalVolume(chnInf->chnstat(), vmp, mainVolume));
1424 			break;
1425 		}
1426 
1427 		// volume slide
1428 		case 0x0A:
1429 		{
1430 			doTickVolslidePT(chnInf, effcnt);
1431 			break;
1432 		}
1433 
1434 		// global volume slide
1435 		case 0x11:
1436 		{
1437 			x = chnInf->old[effcnt].gvolslide>>4;
1438 			y = chnInf->old[effcnt].gvolslide&0xf;
1439 
1440 			if (x&&y) y = 0;
1441 
1442 			if (ticker) {
1443 				if (x) {
1444 					mainVolume+=x*4;
1445 					if (mainVolume>255) mainVolume=255;
1446 				}
1447 				if (y) {
1448 					mainVolume-=y*4;
1449 					if (mainVolume<0) mainVolume=0;
1450 				}
1451 			}
1452 
1453 			break;
1454 		}
1455 
1456 		// deal with eventual tempo slide
1457 		case 0x16:
1458 		{
1459 			if (!ticker ||
1460 				chnInf->old[effcnt].temposlide >= 0x20 ||
1461 				!(module->header.flags & XModule::MODULE_ITTEMPOSLIDE))
1462 				break;
1463 
1464 			x = chnInf->old[effcnt].temposlide>>4;
1465 			y = chnInf->old[effcnt].temposlide&0xf;
1466 
1467 			switch (x >> 4)
1468 			{
1469 				case 0:
1470 					bpm-=y & 0x0F;
1471 					if (bpm < 32)
1472 						bpm = 32;
1473 					break;
1474 				case 1:
1475 					bpm+=y & 0x0F;
1476 					if (bpm > 255)
1477 						bpm = 255;
1478 					break;
1479 			}
1480 
1481 			this->adder = getbpmrate(bpm);
1482 			break;
1483 		}
1484 
1485 		// panning slide
1486 		case 0x19:
1487 		{
1488 			x = chnInf->old[effcnt].panslide>>4;
1489 			y = chnInf->old[effcnt].panslide&0xf;
1490 
1491 			if (x&&y) y = 0;
1492 
1493 			if (ticker) {
1494 				if (x) {
1495 					chnInf->incPan(x);
1496 				}
1497 				if (y) {
1498 					chnInf->decPan(y);
1499 				}
1500 			}
1501 
1502 			break;
1503 		}
1504 
1505 		// retrig + volslide (I worked my ass OFF on this fucking shit)
1506 		// A few notes about FT2 playback:
1507 		// Rxx Retrig doesn't restart envelopes, even with instrument set
1508 		// It only retrigs if the last note has been been within valid range: 1 <= note <= XModule::NOTE_LAST
1509 		case 0x1B:
1510 		{
1511 			if ((chnInf->old[effcnt].retrig&0xf)) {
1512 				if (chnInf->retrigcounterRxx[effcnt] >= chnInf->retrigmaxRxx[effcnt])
1513 				{
1514 					chnInf->retrigcounterRxx[effcnt] = 0;
1515 					chnInf->retrigmaxRxx[effcnt] = chnInf->old[effcnt].retrig&0xf;
1516 
1517 					switch (chnInf->old[effcnt].retrig>>4) {
1518 						case 0x1 :
1519 							chnInf->decVol(4);
1520 							break;
1521 						case 0x2 :
1522 							chnInf->decVol(8);
1523 							break;
1524 						case 0x3 :
1525 							chnInf->decVol(16);
1526 							break;
1527 						case 0x4 :
1528 							chnInf->decVol(32);
1529 							break;
1530 						case 0x5 :
1531 							chnInf->decVol(64);
1532 							break;
1533 						case 0x6 :
1534 							chnInf->setVol(chnInf->getVol()*2/3);
1535 							break;
1536 						case 0x7 :
1537 							chnInf->setVol(chnInf->getVol()>>1);
1538 							break;
1539 						case 0x9 :
1540 							chnInf->incVol(4);
1541 							break;
1542 						case 0xA :
1543 							chnInf->incVol(8);
1544 							break;
1545 						case 0xB :
1546 							chnInf->incVol(16);
1547 							break;
1548 						case 0xC :
1549 							chnInf->incVol(32);
1550 							break;
1551 						case 0xD :
1552 							chnInf->incVol(64);
1553 							break;
1554 						case 0xE :
1555 						{
1556 							mp_sint32 vol = (chnInf->getVol()*3) >> 1;
1557 							if (vol > 255) vol = 255;
1558 							chnInf->setVol(vol);
1559 							break;
1560 						}
1561 						case 0xF :
1562 						{
1563 							mp_sint32 vol = chnInf->getVol() << 1;
1564 							if (vol > 255) vol = 255;
1565 							chnInf->setVol(vol);
1566 							break;
1567 						}
1568 					}
1569 
1570 					chnInf->adjustTremoloTremorVol();
1571 
1572 					if (chnInf->validnote)
1573 						playInstrument(chnInf);
1574 				}
1575 
1576 				chnInf->retrigcounterRxx[effcnt]++;
1577 			}
1578 			break;
1579 		}
1580 
1581 		// tremor (I worked my ass OFF on this fucking shit)
1582 		case 0x1D:
1583 		{
1584 			x = (chnInf->old[effcnt].tremor>>4) + 1;
1585 			y = (chnInf->old[effcnt].tremor&0xf) + 1;
1586 
1587 			mp_sint32 v = (ticker == 0 ? chnInf->getVol() : chnInf->getTremorVol());
1588 
1589 			if (ticker && chnInf->tremorcnt[effcnt] % (x+y) >= x)
1590 				v = 0;
1591 
1592 			if (ticker)
1593 				chnInf->tremorcnt[effcnt]++;
1594 
1595 			if (ticker == tickSpeed - 1)
1596 			{
1597 				chnInf->setVol(v);
1598 				chnInf->adjustTremoloVol();
1599 			}
1600 
1601 			if (chn >= 0)
1602 				setVol(chn,getFinalVolume(chnInf->chnstat(), v, mainVolume));
1603 			break;
1604 		}
1605 
1606 		// MDL/IT Subcommands
1607 		case 0x1E:
1608 		{
1609 			mp_ubyte eff = chnInf->eop[effcnt]>>4;
1610 			mp_ubyte eop = chnInf->eop[effcnt]&0xf;
1611 			switch (eff) {
1612 				case 0x1 :
1613 					if (ticker) {
1614 						chnInf->decPan(eop);
1615 					}
1616 					break;
1617 				case 0x2 :
1618 					if (ticker) {
1619 						chnInf->incPan(eop);
1620 					}
1621 					break;
1622 				case 0xA :
1623 					if (ticker) {
1624 						mainVolume+=eop;
1625 						if (mainVolume>255) mainVolume=255;
1626 					}
1627 					break;
1628 				case 0xB :
1629 					if (ticker) {
1630 						mainVolume-=eop;
1631 						if (mainVolume<0) mainVolume=0;
1632 					}
1633 					break;
1634 			}
1635 			break;
1636 		}
1637 
1638 		// arpeggio
1639 		case 0x20:
1640 		{
1641 			if (chnInf->getNote())
1642 			{
1643 				mp_ubyte arpegLUT[3];
1644 
1645 				mp_sint32 r = 0;
1646 				mp_sint32 note = 0, onote = chnInf->getNote();
1647 				//mp_sint32 c4spd = chnInf->c4spd;
1648 				mp_sint32 relnote = chnInf->getRelnote();
1649 				mp_sint32 finetune = chnInf->getFinetune();
1650 				mp_sint32 per,nper;
1651 
1652 				mp_ubyte eop = chnInf->old[effcnt].arpeg;
1653 
1654 				mp_sint32 x = eop>>4;
1655 				mp_sint32 y = eop&0xf;
1656 
1657 				if (playModeFT2)
1658 				{
1659 					// dammit, FT2 arpeggios are so screwed:
1660 					// the first 11 tick speeds and their arpeggio patterns (0 is note, 3 is fx digit 3, 2 is fx digit 2):
1661 					// 0: Totally fucked up. Just test it.
1662 					// 1: 0
1663 					// 2: 02
1664 					// 3: 032
1665 					// 4: 0032
1666 					// 5: 02320
1667 					// 6: 032032
1668 					// 7: 0032032
1669 					// 8: 02032032
1670 					// 9: 032032032
1671 					// A: 0032032032
1672 					if (ticker == 0)
1673 						r = 0;
1674 					else
1675 						r = myMod(ticker-tickSpeed,3);
1676 
1677 					arpegLUT[0] = 0; arpegLUT[1] = 2; arpegLUT[2] = 1;
1678 				}
1679 				else
1680 				{
1681 					r = (ticker)%3;
1682 
1683 					arpegLUT[0] = 0; arpegLUT[1] = 1; arpegLUT[2] = 2;
1684 				}
1685 
1686 				if (arpegLUT[r] == 0)
1687 				{
1688 					note=chnInf->getNote();
1689 				}
1690 				else if (arpegLUT[r] == 1)
1691 				{
1692 					note=chnInf->getNote()+x;
1693 				}
1694 				else if (arpegLUT[r] == 2)
1695 				{
1696 					note=chnInf->getNote()+y;
1697 				}
1698 
1699 
1700 				// Perform note clipping for XM note range if necessary
1701 				if ((arpegLUT[r] != 0) && // Only done for arpeggio tick 1 & 2
1702 					(module->header.flags & XModule::MODULE_XMNOTECLIPPING) && // Only when enabled
1703 					(note + relnote > 96)) // Only when exceeding range
1704 				{
1705 					note-=((note+relnote) - 97);
1706 				}
1707 
1708 				// special case for STM arpeggio (thanks to Skaven/FC)
1709 				// Will not work in combination with other period
1710 				// related effects
1711 				if (module->header.flags & XModule::MODULE_STMARPEGGIO)
1712 				{
1713 					chnInf->setPer(getperiod(note,relnote,finetune));
1714 					if (chn >= 0)
1715 						setFreq(chn,getFinalFreq(chnInf->chnstat(),getFinalPeriod(chnInf->chnstat(),chnInf->getPer())));
1716 				}
1717 				else
1718 				{
1719 					nper=getperiod(note,relnote,finetune);
1720 					per=getperiod(onote,relnote,finetune);
1721 
1722 					//nper = (8363*periods[(note-1)%12]*16>>(((note-1)/12)))/c4spd;
1723 					//per = (8363*periods[(onote-1)%12]*16>>(((onote-1)/12)))/c4spd;
1724 
1725 					nper-=per;
1726 					nper+=chnInf->getPer();
1727 
1728 					if (chn >= 0)
1729 						setFreq(chn,getFinalFreq(chnInf->chnstat(),getFinalPeriod(chnInf->chnstat(),nper)));
1730 				}
1731 			}
1732 			break;
1733 		}
1734 
1735 		// normal retrig
1736 		// A few notes about FT2 playback:
1737 		// E9x Retrig does!!! (while Rxx doesn't) restart envelopes, even without instrument set
1738 		// It only retrigs if the last note has been been within valid range: 1 <= note <= XModule::NOTE_LAST
1739 		case 0x39:
1740 		{
1741 			if ((chnInf->eop[effcnt]&0xf) && ticker) {
1742 				if (chnInf->retrigcounterE9x[effcnt] >= chnInf->retrigmaxE9x[effcnt])
1743 				{
1744 					chnInf->retrigcounterE9x[effcnt] = 0;
1745 					chnInf->retrigmaxE9x[effcnt] = chnInf->eop[effcnt]&0xf;
1746 					// trigger envelopes ALWAYS
1747 					triggerInstrumentFX(chnInf);
1748 					chnInf->setKeyon(true);
1749 					// trigger replay only when last note has been valid
1750 					if (chnInf->validnote)
1751 						playInstrument(chnInf);
1752 				}
1753 				chnInf->retrigcounterE9x[effcnt]++;
1754 			}
1755 			break;
1756 		}
1757 
1758 		// note cut
1759 		case 0x3C:
1760 			// S3M ignores tick 0 note cut
1761 			if ((module->header.flags & XModule::MODULE_ST3NOTECUT) &&
1762 				!chnInf->eop[effcnt])
1763 				break;
1764 
1765 			// Fasttracker cuts note at tick 0
1766 			//if (chnInf->eop[effcnt]) {
1767 				if (ticker == chnInf->eop[effcnt])
1768 				{
1769 					chnInf->setVol(0);
1770 					chnInf->adjustTremoloTremorVol();
1771 				}
1772 			//}
1773 			break;
1774 
1775 		// MDL porta up
1776 		case 0x43:
1777 			if (ticker) {
1778 				if (chnInf->old[effcnt].portaup<=0xDF) {
1779 					chnInf->decPer(chnInf->old[effcnt].portaup*4);
1780 					handlePeriodUnderflow(chnInf);
1781 					chnInf->adjustVibratoPer();
1782 				}
1783 			}
1784 			break;
1785 
1786 		// MDL porta down
1787 		case 0x44:
1788 			if (ticker) {
1789 				if (chnInf->old[effcnt].portaup<=0xDF) {
1790 					chnInf->incPer(chnInf->old[effcnt].portaup*4);
1791 					handlePeriodOverflow(chnInf);
1792 					chnInf->adjustVibratoPer();
1793 				}
1794 			}
1795 			break;
1796 
1797 		// MDL volslide up
1798 		case 0x45:
1799 			if (ticker) {
1800 				if (chnInf->old[effcnt].volslide<=0xDF) {
1801 					chnInf->incVol(chnInf->old[effcnt].volslide);
1802 					chnInf->adjustTremoloTremorVol();
1803 				}
1804 			}
1805 			break;
1806 
1807 		// MDL volslide down
1808 		case 0x46:
1809 			if (ticker) {
1810 				if (chnInf->old[effcnt].volslide<=0xDF) {
1811 					chnInf->decVol(chnInf->old[effcnt].volslide);
1812 					chnInf->adjustTremoloTremorVol();
1813 				}
1814 			}
1815 			break;
1816 
1817 		// S3M porta up
1818 		case 0x47:
1819 			if (ticker) {
1820 				const mp_sint32 effidx = ((module->header.flags & XModule::MODULE_XMPORTANOTEBUFFER)  && numEffects == 2) ? 1 : effcnt;
1821 				mp_ubyte* op = (module->header.flags & XModule::MODULE_ITLINKPORTAMEM) ?
1822 					&chnInf->old[effidx].portanote : &chnInf->old[effidx].portaup;
1823 				if (*op<=0xDF) {
1824 					chnInf->decPer(*op*4);
1825 					// Special for ST3
1826 					if (chnInf->getPer() <= 0 && chn >= 0)
1827 						stopSample(chn);
1828 					chnInf->adjustVibratoPer();
1829 				}
1830 			}
1831 			break;
1832 
1833 		// S3M porta down
1834 		case 0x48:
1835 			if (ticker) {
1836 				const mp_sint32 effidx = ((module->header.flags & XModule::MODULE_XMPORTANOTEBUFFER)  && numEffects == 2) ? 1 : effcnt;
1837 				mp_ubyte* op = (module->header.flags & XModule::MODULE_ITLINKPORTAMEM) ?
1838 					&chnInf->old[effidx].portanote : &chnInf->old[effidx].portaup;
1839 				if (*op<=0xDF) {
1840 					chnInf->incPer(*op*4);
1841 					chnInf->adjustVibratoPer();
1842 				}
1843 			}
1844 			break;
1845 
1846 		// S3M volslide
1847 		case 0x49:
1848 		{
1849 			doTickVolslideST(chnInf, effcnt);
1850 			break;
1851 		}
1852 
1853 		// fine vibrato
1854 		case 0x4A:
1855 		{
1856 			x = chnInf->eop[effcnt]>>4;
1857 			y = chnInf->eop[effcnt]&0xf;
1858 
1859 			if (x) chnInf->vibspeed[effcnt]=x;
1860 			if (y) chnInf->vibdepth[effcnt]=y;
1861 
1862 			mp_sint32 vmp = chnInf->getPer();
1863 
1864 			vm = calcVibrato(chnInf, effcnt, 7);
1865 
1866 			vp = chnInf->vibpos[effcnt];
1867 
1868 			if (ticker || (module->header.flags & XModule::MODULE_ITNEWEFFECTS))
1869 				chnInf->vibpos[effcnt]+=chnInf->vibspeed[effcnt];
1870 
1871 			vmp+=vm;
1872 
1873 			if (chn >= 0)
1874 				setFreq(chn,getFinalFreq(chnInf->chnstat(),getFinalPeriod(chnInf->chnstat(),vmp)));
1875 			break;
1876 		}
1877 
1878 		// high precision portamento up
1879 		case 0x4D:
1880 			if (ticker) {
1881 				chnInf->decPer(chnInf->old[effcnt].portaup);
1882 				handlePeriodUnderflow(chnInf);
1883 				chnInf->adjustVibratoPer();
1884 			}
1885 			break;
1886 
1887 		// high precision portamento down
1888 		case 0x4E:
1889 			if (ticker) {
1890 				chnInf->incPer(chnInf->old[effcnt].portaup);
1891 				handlePeriodOverflow(chnInf);
1892 				chnInf->adjustVibratoPer();
1893 			}
1894 			break;
1895 
1896 		// XM: Key off at tick
1897 		case 0x14:
1898 			// not at tick 0
1899 			if (!ticker)
1900 				break;
1901 		// AMS: Key off at tick
1902 		case 0x51:
1903 			if (ticker == chnInf->eop[effcnt])
1904 			{
1905 				if (chnInf->getVenv().envstruc!=NULL) {
1906 					if (!chnInf->getVenv().isEnabled())
1907 						chnInf->setVol(0);
1908 				}
1909 				else
1910 					chnInf->setVol(0);
1911 
1912 				chnInf->adjustTremoloTremorVol();
1913 
1914 				chnInf->setKeyon(false);
1915 			}
1916 			break;
1917 
1918 		// Oktalyzer arpeggio I, II, III
1919 		case 0x56:
1920 		case 0x57:
1921 		case 0x58:
1922 		{
1923 			if (chnInf->getNote())
1924 			{
1925 				mp_sint32 eff = chnInf->eff[effcnt]-0x56;
1926 				mp_sint32 r;
1927 
1928 				if (eff == 1)
1929 					r = (ticker)&3;
1930 				else
1931 					r = (ticker)%3;
1932 
1933 				mp_sint32 note = 0,onote = chnInf->getNote();
1934 				mp_sint32 relnote = chnInf->getRelnote();
1935 				mp_sint32 finetune = chnInf->getFinetune();
1936 				mp_sint32 per,nper;
1937 
1938 				mp_ubyte eop = chnInf->eop[effcnt];
1939 
1940 				mp_sint32 x = eop>>4;
1941 				mp_sint32 y = eop&0xf;
1942 
1943 				switch (eff)
1944 				{
1945 					case 0x00:
1946 					{
1947 						switch (r) {
1948 							case 0 : note=chnInf->getNote()-x; break;
1949 							case 1 : note=chnInf->getNote(); break;
1950 							case 2 : note=chnInf->getNote()+y; break;
1951 						}
1952 						break;
1953 					}
1954 
1955 					case 0x01:
1956 					{
1957 						switch (r) {
1958 							case 0 : note=chnInf->getNote(); break;
1959 							case 1 : note=chnInf->getNote()+y; break;
1960 							case 2 : note=chnInf->getNote(); break;
1961 							case 3 : note=chnInf->getNote()-x; break;
1962 						}
1963 						break;
1964 					}
1965 
1966 					case 0x02:
1967 					{
1968 						switch (r) {
1969 							case 0 : note=chnInf->getNote()+y; break;
1970 							case 1 : note=chnInf->getNote()+y; break;
1971 							case 2 : note=chnInf->getNote(); break;
1972 						}
1973 						break;
1974 					}
1975 				}
1976 
1977 				nper=getperiod(note,relnote,finetune);
1978 				per=getperiod(onote,relnote,finetune);
1979 
1980 				nper-=per;
1981 				nper+=chnInf->getPer();
1982 
1983 				if (chn >= 0)
1984 					setFreq(chn,getFinalFreq(chnInf->chnstat(),getFinalPeriod(chnInf->chnstat(),nper)));
1985 			}
1986 			break;
1987 		}
1988 
1989 		// Global volslide
1990 		case 0x59:
1991 		{
1992 			if (!(module->header.flags & XModule::MODULE_OLDS3MVOLSLIDES) &&
1993 				ticker == 0)
1994 				break;
1995 
1996 			x = chnInf->old[effcnt].gvolslide>>4;
1997 			y = chnInf->old[effcnt].gvolslide&0xf;
1998 
1999 			if (x == 0xF && y) break;
2000 			if (y == 0xF && x) break;
2001 
2002 			if (x && y) y = 0;
2003 
2004 			if (x) {
2005 				// IT modules increment by 2, all others by 4
2006 				mainVolume+=x*((module->header.flags & XModule::MODULE_ITNOTEOFF) ? 2 : 4);
2007 
2008 				if (mainVolume>255) mainVolume=255;
2009 			}
2010 			if (y) {
2011 				// IT modules decrement by 2, all others by 4
2012 				mainVolume-=y*((module->header.flags & XModule::MODULE_ITNOTEOFF) ? 2 : 4);
2013 				if (mainVolume<0) mainVolume=0;
2014 			}
2015 			break;
2016 		}
2017 		// IT/S3M Channel volslide
2018 		case 0x5A:
2019 		{
2020 			if (!(module->header.flags & XModule::MODULE_OLDS3MVOLSLIDES) &&
2021 				ticker == 0)
2022 				break;
2023 
2024 			x = chnInf->old[effcnt].chnvolslide>>4;
2025 			y = chnInf->old[effcnt].chnvolslide&0xf;
2026 
2027 			if (x == 0xF && y) break;
2028 			if (y == 0xF && x) break;
2029 
2030 			if (x && y) y = 0;
2031 
2032 			if (x) {
2033 				chnInf->incMasterVol(x*4);
2034 			}
2035 			if (y) {
2036 				chnInf->decMasterVol(y*4);
2037 			}
2038 			break;
2039 		}
2040 		// IT panning slide
2041 		case 0x5B:
2042 		{
2043 			if (!(module->header.flags & XModule::MODULE_OLDS3MVOLSLIDES) &&
2044 				ticker == 0)
2045 				break;
2046 
2047 			x = chnInf->old[effcnt].panslide>>4;
2048 			y = chnInf->old[effcnt].panslide&0xf;
2049 
2050 			if (x == 0xF && y) break;
2051 			if (y == 0xF && x) break;
2052 
2053 			if (x && y) y = 0;
2054 
2055 			if (x) {
2056 				chnInf->decPan(x*4);
2057 			}
2058 			if (y) {
2059 				chnInf->incPan(y*4);
2060 			}
2061 			break;
2062 		}
2063 
2064 		// panbrello (Impulse Tracker only)
2065 		case 0x5C:
2066 		{
2067 			x = chnInf->eop[effcnt]>>4;
2068 			y = chnInf->eop[effcnt]&0xf;
2069 			if (x) chnInf->panbrellospeed[effcnt]=x;
2070 			if (y) chnInf->panbrellodepth[effcnt]=y;
2071 
2072 			vp = chnInf->panbrellopos[effcnt];
2073 			vd = chnInf->panbrellodepth[effcnt];
2074 
2075 			mp_sint32 vmp = chnInf->getPan();
2076 
2077 			// IT in new effects mode processes at non row tick
2078 			if (ticker || (module->header.flags & XModule::MODULE_ITNEWEFFECTS))
2079 			{
2080 				// IT in new effects mode is two times finer
2081 				vm = (finesintab[vp&255]*vd) >> ((module->header.flags & XModule::MODULE_ITNEWEFFECTS) ? (3-1) : (3-2));
2082 				vmp+=vm;
2083 				if (vmp<0) vmp=0;
2084 				if (vmp>255) vmp=255;
2085 				chnInf->panbrellopos[effcnt]+=chnInf->panbrellospeed[effcnt];
2086 			}
2087 
2088 			if (chn >= 0)
2089 				setPan(chn, getFinalPanning(chnInf->chnstat(), vmp));
2090 			break;
2091 		}
2092 
2093 	}
2094 }
2095 
doVolslidePT(TModuleChannel * chnInf,mp_sint32 effcnt,mp_ubyte eop)2096 void PlayerIT::doVolslidePT(TModuleChannel* chnInf, mp_sint32 effcnt, mp_ubyte eop)
2097 {
2098 	if (eop) chnInf->old[effcnt].volslide=eop;
2099 }
2100 
doVolslideST(TModuleChannel * chnInf,mp_sint32 effcnt,mp_ubyte eop)2101 void PlayerIT::doVolslideST(TModuleChannel* chnInf, mp_sint32 effcnt, mp_ubyte eop)
2102 {
2103 	if (eop) chnInf->old[effcnt].volslide=eop;
2104 
2105 	if (chnInf->old[effcnt].volslide) {
2106 		mp_ubyte y=chnInf->old[effcnt].volslide>>4;
2107 		mp_ubyte x=chnInf->old[effcnt].volslide&0xf;
2108 
2109 		if ((x!=0x0F)&&(y!=0x0F)) return;
2110 		if (x==0x0F && !y) return;
2111 		if (y==0x0F && !x) return;
2112 
2113 		if (x==0x0F)
2114 		{
2115 			chnInf->incVol(y*4);
2116 			chnInf->adjustTremoloTremorVol();
2117 			return;
2118 		}
2119 		if (y==0x0F)
2120 		{
2121 			chnInf->decVol(x*4);
2122 			chnInf->adjustTremoloTremorVol();
2123 			return;
2124 		}
2125 	}
2126 }
2127 
doEffect(TModuleChannel * chnInf,mp_sint32 effcnt)2128 void PlayerIT::doEffect(TModuleChannel* chnInf, mp_sint32 effcnt)
2129 {
2130 	const mp_sint32 chn = chnInf->getPlaybackChannelIndex();
2131 
2132 	mp_ubyte x,y;
2133 	mp_sint32 eop=chnInf->eop[effcnt];
2134 	switch (chnInf->eff[effcnt]) {
2135 		case 0x01 : if (eop) chnInf->old[effcnt].portaup=eop; break;
2136 		case 0x02 : if (eop) chnInf->old[effcnt].portadown=eop; break;
2137 		case 0x03 : if (module->header.flags & XModule::MODULE_XMPORTANOTEBUFFER)
2138 					{
2139 						ASSERT(numEffects >= 2);
2140 						if (eop) chnInf->old[1].portanote=eop;
2141 					}
2142 					else
2143 					{
2144 						if (eop) chnInf->old[effcnt].portanote=eop;
2145 					}
2146 					break;
2147 		case 0x05 :
2148 		case 0x06 : {
2149 						if (module->header.flags & XModule::MODULE_ST3DUALCOMMANDS)
2150 							doVolslideST(chnInf, effcnt, eop);
2151 						else
2152 							doVolslidePT(chnInf, effcnt, eop);
2153 						break;
2154 					}
2155 		case 0x08 : if (options[PlayModeOptionPanning8xx]) chnInf->setPan(eop); break;
2156 		case 0x09 : {
2157 						if (eop) chnInf->old[effcnt].smpoffset = eop;
2158 						chnInf->smpoffs = chnInf->old[effcnt].smpoffset<<8;
2159 					};
2160 					break;
2161 		case 0x0A : doVolslidePT(chnInf, effcnt, eop); break;
2162 		case 0x0B : {
2163 						pjump = 1;
2164 						pjumppos = eop;
2165 						pjumprow = 0;
2166 						pjumpPriority = MP_NUMEFFECTS*chnInf->channelIndex + effcnt;
2167 					};
2168 					break;
2169 		case 0x0C : chnInf->setVol(eop);
2170 					chnInf->adjustTremoloTremorVol();
2171 					chnInf->hasSetVolume = true;
2172 					break;
2173 		case 0x0D : {
2174 						pbreak=1;
2175 						pbreakpos = (eop>>4)*10+(eop&0xf);
2176 						if (pbreakpos > 63)
2177 							pbreakpos = 0;
2178 						pbreakPriority = MP_NUMEFFECTS*chnInf->channelIndex + effcnt;
2179 					}; break;
2180 		case 0x0F : {
2181 						if (eop)
2182 						{
2183 							if (eop>=32) {
2184 								bpm=eop;
2185 								this->adder = getbpmrate(eop);
2186 							}
2187 						}
2188 						else
2189 						{
2190 							haltFlag = true;
2191 						}
2192 					}; break;
2193 		case 0x10 : mainVolume=eop; break;
2194 		case 0x11 : if (eop) chnInf->old[effcnt].gvolslide=eop; break;
2195 		// set envelope position
2196 		case 0x15 : {
2197 						if (chnInf->getVenv().envstruc == NULL)
2198 							break;
2199 
2200 						bool bSet = false;
2201 
2202 						TPrEnv* env = &chnInf->getVenv();
2203 
2204 						for (mp_sint32 i = 0; i < env->envstruc->num-1; i++)
2205 						{
2206 							if (eop >= env->envstruc->env[i][0] &&
2207 								eop < env->envstruc->env[i+1][0])
2208 							{
2209 								env->a = i;
2210 								env->b = i+1;
2211 								env->step = eop;
2212 
2213 								bSet = true;
2214 								break;
2215 							}
2216 						}
2217 
2218 						if (!bSet)
2219 						{
2220 							// if position is beyond the last envelope point
2221 							// we limit it to the last point and exit
2222 							bool beyond = eop > env->envstruc->env[env->envstruc->num-1][0];
2223 							env->a = env->envstruc->num-1;
2224 							env->b = env->envstruc->num;
2225 							env->step = env->envstruc->env[env->envstruc->num-1][0];
2226 							if (beyond)
2227 								break;
2228 						}
2229 
2230 						// check if we set envelope position to a loop end point
2231 						// in that case wrap to the loop start, otherwise the loop
2232 						// end is skipped and the envelope will roll out without
2233 						// looping
2234 						if ((env->envstruc->type & 4) &&
2235 							env->step == env->envstruc->env[env->envstruc->loope][0])
2236 						{
2237 							env->a=env->envstruc->loops;
2238 							env->b=env->envstruc->loops+1;
2239 							env->step=env->envstruc->env[env->a][0];
2240 						}
2241 						break;
2242 					}
2243 		// set BPM
2244 		case 0x16 : {
2245 						if (eop) {
2246 							chnInf->old[effcnt].temposlide = eop;
2247 							if ((module->header.flags & XModule::MODULE_ITTEMPOSLIDE) && eop < 0x20)
2248 								break;
2249 							bpm=eop;
2250 							this->adder = getbpmrate(eop);
2251 						}
2252 					}; break;
2253 
2254 		case 0x19 : if (eop) chnInf->old[effcnt].panslide=eop; break;
2255 		case 0x1B : {
2256 						x = eop & 0xf;
2257 						y = eop & 0xF0;
2258 
2259 						if (x)
2260 							chnInf->old[effcnt].retrig = (chnInf->old[effcnt].retrig & 0xF0) | x;
2261 						if (y)
2262 							chnInf->old[effcnt].retrig = (chnInf->old[effcnt].retrig & 0x0F) | y;
2263 
2264 						eop = chnInf->old[effcnt].retrig;
2265 
2266 						chnInf->retrigmaxRxx[effcnt] = eop & 0xF;
2267 
2268 						// Simulate really nasty FT2 bug:
2269 						// When a volume is set in the volume column
2270 						// the interval for the first retrig is lengthen by one tick
2271 						if (chnInf->hasSetVolume && playModeFT2)
2272 						{
2273 							chnInf->retrigcounterRxx[effcnt] = -1;
2274 							chnInf->hasSetVolume = false;
2275 						}
2276 
2277 						// If a note is playing on tick 0, increase counter
2278 						if (chnInf->currentnote && chnInf->validnote)
2279 							chnInf->retrigcounterRxx[effcnt]++;
2280 						break;
2281 					}
2282 		// Tremor
2283 		case 0x1D : if (eop) chnInf->old[effcnt].tremor=eop; break;
2284 		// MDL/IT Subcommands
2285 		case 0x1E:
2286 		{
2287 			mp_ubyte eff = chnInf->eop[effcnt] >> 4;
2288 			mp_ubyte eop = chnInf->eop[effcnt] & 0xf;
2289 			switch (eff)
2290 			{
2291 				// past note actions/envelope trigger control etc.
2292 				case 0x7:
2293 				{
2294 					switch (eop)
2295 					{
2296 						case 0x0:
2297 						case 0x1:
2298 						case 0x2:
2299 							handlePastNoteAction(chnInf, eop);
2300 							break;
2301 						// set NNA to cut/continue/note off/note fade
2302 						case 0x3:
2303 						case 0x4:
2304 						case 0x5:
2305 						case 0x6:
2306 							// clear out bits 4 and 5
2307 							// shift new NNA value into the position
2308 							chnInf->setInsflags((chnInf->getInsflags() & ~(3 << 4)) | ((eop-0x03) << 4));
2309 							break;
2310 						// turn off volume envelope
2311 						case 0x7:
2312 							chnInf->getVenv().setEnabled(false);
2313 							break;
2314 						// turn on volume envelope
2315 						case 0x8:
2316 							chnInf->getVenv().setEnabled(true);
2317 							break;
2318 						// turn off panning envelope
2319 						case 0x9:
2320 							chnInf->getPenv().setEnabled(false);
2321 							break;
2322 						// turn on panning envelope
2323 						case 0xA:
2324 							chnInf->getPenv().setEnabled(true);
2325 							break;
2326 						// turn off pitch envelope
2327 						case 0xB:
2328 							chnInf->getPitchenv().setEnabled(false);
2329 							break;
2330 						// turn on pitch envelope
2331 						case 0xC:
2332 							chnInf->getPitchenv().setEnabled(true);
2333 							break;
2334 					}
2335 					break;
2336 				}
2337 				// set high sample offset
2338 				case 0xF:
2339 				{
2340 					chnInf->smpoffshigh = (mp_uint32)eop << 16;
2341 					break;
2342 				}
2343 			}
2344 			break;
2345 		}
2346 		// MDL set sample offset
2347 		case 0x1F : {
2348 						chnInf->smpoffs=((mp_sint32)eop<<8)+((mp_sint32)chnInf->eop[(effcnt+1)%numEffects]<<16);
2349 					}; break;
2350 		case 0x20 : if (eop) chnInf->old[effcnt].arpeg=eop; break;
2351 		// ULT set sample offset
2352 		case 0x21 : {
2353 						chnInf->smpoffs=((mp_sint32)eop<<10);
2354 					}; break;
2355 		// ULT Fine set sample offset
2356 		case 0x22 : {
2357 						mp_sint32 op = (((mp_sint32)eop)<<8) + ((mp_sint32)chnInf->eop[(effcnt+1)%numEffects]);
2358 						chnInf->smpoffs=op<<2;
2359 					}; break;
2360 		// ULT special commands
2361 		case 0x23 : {
2362 						if (((eop >> 4) == 1 || (eop&0xF) == 1) ||
2363 							((eop >> 4) == 12 || (eop&0xF) == 12))
2364 						{
2365 							if (chn < 0)
2366 								break;
2367 							breakLoop(chn);
2368 						}
2369 						if ((eop >> 4) == 2 || (eop&0xF) == 2)
2370 						{
2371 							chnInf->resetFlag(CHANNEL_FLAGS_FORCE_FORWARD);
2372 							chnInf->setFlag(CHANNEL_FLAGS_FORCE_BACKWARD);
2373 							if (chn < 0)
2374 								break;
2375 							setBackward(chn);
2376 						}
2377 					}; break;
2378 		// Far position jump (PLM support)
2379 		case 0x2B : {
2380 						pjump = 1;
2381 						pjumppos = eop;
2382 						pjumprow = chnInf->eop[(effcnt+1)%numEffects];
2383 						pjumpPriority = MP_NUMEFFECTS*chnInf->channelIndex + effcnt;
2384 					}; break;
2385 		// Fine porta up
2386 		case 0x31 : {
2387 						if (eop) chnInf->old[effcnt].fineportaup=eop;
2388 						chnInf->decPer(chnInf->old[effcnt].fineportaup*4);
2389 						handlePeriodUnderflow(chnInf);
2390 						chnInf->adjustVibratoPer();
2391 					}; break;
2392 		// Fine porta down
2393 		case 0x32 : {
2394 						if (eop) chnInf->old[effcnt].fineportadown=eop;
2395 						chnInf->incPer(chnInf->old[effcnt].fineportadown*4);
2396 						handlePeriodOverflow(chnInf);
2397 						chnInf->adjustVibratoPer();
2398 					}; break;
2399 		case 0x36 : {
2400 						mp_ubyte op = eop;
2401 
2402 						// Imitate IT/ST3 behaviour
2403 						// not only S60 can be the loop start point
2404 						// if we jump back to the start row, ignore the argument of this S6x
2405 						if (newInsST3Flag && (chnInf->loopstart==rowcnt) && chnInf->isLooping)
2406 							op = 0;
2407 
2408 						if (!op) {
2409 							chnInf->execloop=0;
2410 							chnInf->loopstart=rowcnt;
2411 							chnInf->loopingValidPosition = poscnt;
2412 						}
2413 						else {
2414 							if (chnInf->loopcounter==op)
2415 							{
2416 								// Imitate nasty XM bug here:
2417 								if (playModeFT2)
2418 								{
2419 									startNextRow = chnInf->loopstart;
2420 								}
2421 
2422 								RESETLOOPING
2423 
2424 								// Imitate IT/ST3 behaviour
2425 								// not only S60 can be the loop start point
2426 								if (newInsST3Flag)
2427 								{
2428 									chnInf->execloop=0;
2429 									chnInf->loopstart=rowcnt;
2430 									chnInf->loopingValidPosition = poscnt;
2431 								}
2432 							}
2433 							else {
2434 								chnInf->execloop=1;
2435 								chnInf->loopcounter++;
2436 							}
2437 						}
2438 					}; break;
2439 		case 0x38 : if (options[PlayModeOptionPanningE8x]) chnInf->setPan((mp_ubyte)XModule::pan15to255(eop)); break;
2440 		case 0x39 : {
2441 						chnInf->retrigcounterE9x[effcnt] = 0;
2442 						if (eop)
2443 						{
2444 							chnInf->retrigmaxE9x[effcnt] = eop & 0xF;
2445 
2446 							// If a note is playing on tick 0, increase counter
2447 							if (chnInf->currentnote && chnInf->validnote)
2448 								chnInf->retrigcounterE9x[effcnt]++;
2449 						}
2450 						else if (!chnInf->currentnote)
2451 						{
2452 							// trigger envelopes ALWAYS
2453 							triggerInstrumentFX(chnInf);
2454 							chnInf->setKeyon(true);
2455 							// trigger replay only when last note has been valid
2456 							if (chnInf->validnote)
2457 								playInstrument(chnInf);
2458 						}
2459 					}; break;
2460 		case 0x3A : {
2461 						if (eop) chnInf->old[effcnt].finevolslide=eop;
2462 						chnInf->incVol(chnInf->old[effcnt].finevolslide*4);
2463 						chnInf->adjustTremoloTremorVol();
2464 					}; break;
2465 		case 0x3B : {
2466 						if (eop) chnInf->old[effcnt].finevolslide=eop;
2467 						chnInf->decVol(chnInf->old[effcnt].finevolslide*4);
2468 						chnInf->adjustTremoloTremorVol();
2469 					}; break;
2470 		// Note delay triggers envelopes/autovibrato/fade out again
2471 		case 0x3D : {
2472 						triggerInstrumentFX(chnInf);
2473 						chnInf->setKeyon(true);
2474 					}; break;
2475 		case 0x3E : {
2476 						patDelay = true;
2477 						patDelayCount = (mp_sint32)tickSpeed*((mp_sint32)eop+1);
2478 					}; break;
2479 		// Xtra fine porta up
2480 		case 0x41 : {
2481 						if (eop) chnInf->old[effcnt].xfineportaup=eop;
2482 						chnInf->decPer(chnInf->old[effcnt].xfineportaup);
2483 						handlePeriodUnderflow(chnInf);
2484 						chnInf->adjustVibratoPer();
2485 					}; break;
2486 		case 0x42 : {
2487 						if (eop) chnInf->old[effcnt].xfineportadown=eop;
2488 						chnInf->incPer(chnInf->old[effcnt].xfineportadown);
2489 						handlePeriodOverflow(chnInf);
2490 						chnInf->adjustVibratoPer();
2491 					}; break;
2492 		// MDL fine portas up
2493 		case 0x43 : {
2494 						if (eop) chnInf->old[effcnt].portaup=eop;
2495 						if (chnInf->old[effcnt].portaup>=0xE0) {
2496 							y=chnInf->old[effcnt].portaup>>4;
2497 							x=chnInf->old[effcnt].portaup&0xf;
2498 							switch (y) {
2499 								case 0xF:
2500 									chnInf->decPer(x*4);
2501 									handlePeriodUnderflow(chnInf);
2502 									chnInf->adjustVibratoPer();
2503 									break;
2504 								case 0xE:
2505 									chnInf->decPer(x>>1);
2506 									handlePeriodUnderflow(chnInf);
2507 									chnInf->adjustVibratoPer();
2508 									break;
2509 							}
2510 						}
2511 					}; break;
2512 		case 0x44 : {
2513 						if (eop) chnInf->old[effcnt].portaup=eop;
2514 						if (chnInf->old[effcnt].portaup>=0xE0) {
2515 							y=chnInf->old[effcnt].portaup>>4;
2516 							x=chnInf->old[effcnt].portaup&0xf;
2517 							switch (y) {
2518 								case 0xF :
2519 									chnInf->incPer(x*4);
2520 									handlePeriodOverflow(chnInf);
2521 									chnInf->adjustVibratoPer();
2522 									break;
2523 								case 0xE :
2524 									chnInf->incPer(x>>1);
2525 									handlePeriodOverflow(chnInf);
2526 									chnInf->adjustVibratoPer();
2527 									break;
2528 							}
2529 						}
2530 					}; break;
2531 		case 0x45 : {
2532 						if (eop) chnInf->old[effcnt].volslide=eop;
2533 						if (chnInf->old[effcnt].volslide>=0xE0) {
2534 							y=chnInf->old[effcnt].volslide>>4;
2535 							x=chnInf->old[effcnt].volslide&0xf;
2536 							switch (y) {
2537 								case 0xF :
2538 									chnInf->incVol(x*4);
2539 									chnInf->adjustTremoloTremorVol();
2540 									break;
2541 								case 0xE :
2542 									chnInf->incVol(x);
2543 									chnInf->adjustTremoloTremorVol();
2544 									break;
2545 							}
2546 						}
2547 					}
2548 					break;
2549 		case 0x46 : {
2550 						if (eop) chnInf->old[effcnt].volslide=eop;
2551 						if (chnInf->old[effcnt].volslide>=0xE0) {
2552 							y=chnInf->old[effcnt].volslide>>4;
2553 							x=chnInf->old[effcnt].volslide&0xf;
2554 							switch (y) {
2555 								case 0xF :
2556 									chnInf->decVol(x*4);
2557 									chnInf->adjustTremoloTremorVol();
2558 									break;
2559 								case 0xE :
2560 									chnInf->decVol(x);
2561 									chnInf->adjustTremoloTremorVol();
2562 									break;
2563 							}
2564 						}
2565 					}; break;
2566 		// S3M porta up
2567 		case 0x47 : {
2568 						// when MODULE_XMPORTANOTEBUFFER is set
2569 						// we link all effects to the second effect memory
2570 						const mp_sint32 effidx = ((module->header.flags & XModule::MODULE_XMPORTANOTEBUFFER)  && numEffects == 2) ? 1 : effcnt;
2571 						mp_ubyte* op = (module->header.flags & XModule::MODULE_ITLINKPORTAMEM) ?
2572 							&chnInf->old[effidx].portanote : &chnInf->old[effidx].portaup;
2573 						if (eop) *op=eop;
2574 						if (*op>=0xE0) {
2575 							y=*op>>4;
2576 							x=*op&0xf;
2577 							switch (y) {
2578 								case 0xF:
2579 									chnInf->decPer(x*4);
2580 									// Special for ST3
2581 									if (chnInf->getPer() <= 0 && chn >= 0)
2582 										stopSample(chn);
2583 									chnInf->adjustVibratoPer();
2584 									break;
2585 								case 0xE:
2586 									chnInf->decPer(x);
2587 									// Special for ST3
2588 									if (chnInf->getPer() <= 0 && chn >= 0)
2589 										stopSample(chn);
2590 									chnInf->adjustVibratoPer();
2591 									break;
2592 							}
2593 						}
2594 					}; break;
2595 		// S3M porta down
2596 		case 0x48 : {
2597 						// when MODULE_XMPORTANOTEBUFFER is set
2598 						// we link all effects to the second effect memory
2599 						const mp_sint32 effidx = ((module->header.flags & XModule::MODULE_XMPORTANOTEBUFFER)  && numEffects == 2) ? 1 : effcnt;
2600 						mp_ubyte* op = (module->header.flags & XModule::MODULE_ITLINKPORTAMEM) ?
2601 							&chnInf->old[effidx].portanote : &chnInf->old[effidx].portaup;
2602 						if (eop) *op=eop;
2603 						if (*op>=0xE0) {
2604 							y=*op>>4;
2605 							x=*op&0xf;
2606 							switch (y) {
2607 								case 0xF :
2608 									chnInf->incPer(x*4);
2609 									handlePeriodOverflow(chnInf);
2610 									chnInf->adjustVibratoPer();
2611 									break;
2612 								case 0xE :
2613 									chnInf->incPer(x);
2614 									handlePeriodOverflow(chnInf);
2615 									chnInf->adjustVibratoPer();
2616 									break;
2617 							}
2618 						}
2619 					}; break;
2620 		// S3M volslide
2621 		case 0x49 : doVolslideST(chnInf, effcnt, eop); break;
2622 		// extra fine volslide up (PSM support)
2623 		case 0x4B : {
2624 						if (eop) chnInf->old[effcnt].finevolslide=eop;
2625 						chnInf->incVol(chnInf->old[effcnt].finevolslide);
2626 						chnInf->adjustTremoloTremorVol();
2627 					}; break;
2628 		// extra fine volslide down (PSM support)
2629 		case 0x4C : {
2630 						if (eop) chnInf->old[effcnt].finevolslide=eop;
2631 						chnInf->decVol(chnInf->old[effcnt].finevolslide);
2632 						chnInf->adjustTremoloTremorVol();
2633 					}; break;
2634 		// high precision porta up (PSM support)
2635 		// same as 0x01 but 4x more accurate
2636 		case 0x4D : if (eop) chnInf->old[effcnt].portaup=eop; break;
2637 		// high precision porta down (PSM support)
2638 		// same as 0x02 but 4x more accurate
2639 		case 0x4E : if (eop) chnInf->old[effcnt].portaup=eop; break;
2640 		// AMS: Set sampleflags
2641 		case 0x4F : if (!eop)
2642 					{
2643 						chnInf->resetFlag(CHANNEL_FLAGS_FORCE_BACKWARD);
2644 						chnInf->setFlag(CHANNEL_FLAGS_FORCE_FORWARD);
2645 						if (chn < 0)
2646 							break;
2647 						setForward(chn);
2648 					}
2649 					else if (eop == 1)
2650 					{
2651 						chnInf->resetFlag(CHANNEL_FLAGS_FORCE_FORWARD);
2652 						chnInf->setFlag(CHANNEL_FLAGS_FORCE_BACKWARD);
2653 						if (chn < 0)
2654 							break;
2655 						setBackward(chn);
2656 					}
2657 					else if (eop == 2)
2658 					{
2659 						chnInf->setFlag(CHANNEL_FLAGS_FORCE_BILOOP);
2660 					}
2661 					else if (eop == 3)  // break sampleloop / oktalyzer too
2662 					{
2663 						if (chn < 0)
2664 							break;
2665 						breakLoop(chn);
2666 					}
2667 					break;
2668 		// AMS: Set channel mastervol
2669 		case 0x50 : chnInf->setMasterVol(eop); break;
2670 		// Digibooster set real BPM
2671 		case 0x52 : {
2672 						if (eop)
2673 						{
2674 							baseBpm = eop >= 32 ? eop : 32;
2675 							// Simply recalculate
2676 							this->adder = getbpmrate(bpm);
2677 						}
2678 						break;
2679 					}
2680 		// Oktalyzer: fine note slide down
2681 		case 0x54:  {
2682 						if (chnInf->getNote() > eop)
2683 						{
2684 							mp_sint32 note = chnInf->getNote();
2685 							note-=eop;
2686 							if (note < 3*12)
2687 								note = 3*12;
2688 							chnInf->setNote(note);
2689 							chnInf->setPer(getperiod(chnInf->getNote(),chnInf->getRelnote(),chnInf->getFinetune()));
2690 							chnInf->adjustVibratoPer();
2691 						}
2692 					}
2693 					break;
2694 		// Oktalyzer: fine note slide up
2695 		case 0x55:  {
2696 						if (chnInf->getNote() < XModule::NOTE_LAST-eop)
2697 						{
2698 							mp_sint32 note = chnInf->getNote();
2699 							note+=eop;
2700 							if (note > 6*12)
2701 								note = 6*12;
2702 							chnInf->setNote(note);
2703 							chnInf->setPer(getperiod(chnInf->getNote(),chnInf->getRelnote(),chnInf->getFinetune()));
2704 							chnInf->adjustVibratoPer();
2705 						}
2706 					}
2707 					break;
2708 		// IT/S3M global volslide (Impulse Tracker)
2709 		case 0x59 : {
2710 						if (eop) chnInf->old[effcnt].gvolslide=eop;
2711 
2712 						if (chnInf->old[effcnt].gvolslide) {
2713 							y=chnInf->old[effcnt].gvolslide>>4;
2714 							x=chnInf->old[effcnt].gvolslide&0xf;
2715 
2716 							if ((x!=0x0F)&&(y!=0x0F)) break;
2717 							if (x==0x0F && !y) break;
2718 							if (y==0x0F && !x) break;
2719 
2720 							if (x==0x0F)
2721 							{
2722 								mainVolume+=y*((module->header.flags & XModule::MODULE_ITNOTEOFF) ? 2 : 4);
2723 								if (mainVolume>255) mainVolume=255;
2724 								break;
2725 							}
2726 							if (y==0x0F)
2727 							{
2728 								mainVolume-=x*((module->header.flags & XModule::MODULE_ITNOTEOFF) ? 2 : 4);
2729 								if (mainVolume<0) mainVolume=0;
2730 								break;
2731 							}
2732 						}
2733 						break;
2734 					}
2735 		// IT Channel volslide
2736 		case 0x5A : {
2737 						if (eop) chnInf->old[effcnt].chnvolslide=eop;
2738 
2739 						if (chnInf->old[effcnt].chnvolslide) {
2740 							y=chnInf->old[effcnt].chnvolslide>>4;
2741 							x=chnInf->old[effcnt].chnvolslide&0xf;
2742 
2743 							if ((x!=0x0F)&&(y!=0x0F)) break;
2744 							if (x==0x0F && !y) break;
2745 							if (y==0x0F && !x) break;
2746 
2747 							if (x==0x0F)
2748 							{
2749 								chnInf->incMasterVol(y*4);
2750 								break;
2751 							}
2752 							if (y==0x0F)
2753 							{
2754 								chnInf->decMasterVol(x*4);
2755 								break;
2756 							}
2757 						}
2758 					}; break;
2759 		// IT panning slide
2760 		case 0x5B : {
2761 						if (eop) chnInf->old[effcnt].panslide=eop;
2762 
2763 						if (chnInf->old[effcnt].panslide) {
2764 							y=chnInf->old[effcnt].panslide>>4;
2765 							x=chnInf->old[effcnt].panslide&0xf;
2766 
2767 							if ((x!=0x0F)&&(y!=0x0F)) break;
2768 							if (x==0x0F && !y) break;
2769 							if (y==0x0F && !x) break;
2770 
2771 							if (x==0x0F)
2772 							{
2773 								chnInf->decPan(y*4);
2774 								break;
2775 							}
2776 							if (y==0x0F)
2777 							{
2778 								chnInf->incPan(x*4);
2779 								break;
2780 							}
2781 						}
2782 					}; break;
2783 
2784 	} // switch
2785 }
2786 
doTickeffects()2787 void PlayerIT::doTickeffects()
2788 {
2789 	TModuleChannel* chnInf = chninfo;
2790 	for (mp_sint32 chn = 0; chn < numChannels; chn++, chnInf++)
2791 	{
2792 		for (mp_sint32 effcnt = 0; effcnt < numEffects; effcnt++)
2793 		{
2794 			doTickEffect(chnInf, effcnt);
2795 		}
2796 	}
2797 }
2798 
triggerEnvelope(TPrEnv & dstEnv,TEnvelope & srcEnv)2799 void PlayerIT::triggerEnvelope(TPrEnv& dstEnv, TEnvelope& srcEnv)
2800 {
2801 	// if the same envelope has been not been assigned already,
2802 	// we take over the "enabled" flag from the envelope
2803 	if (dstEnv.envstruc != &srcEnv)
2804 		dstEnv.enabled = srcEnv.type & 1;
2805 	dstEnv.envstruc = &srcEnv;
2806 	dstEnv.a = 0;
2807 	dstEnv.b = 1;
2808 	dstEnv.step = 0;
2809 	dstEnv.bpmCounter = 0;
2810 	if (dstEnv.envstruc->speed)
2811 		dstEnv.bpmAdder = getbpmrate(dstEnv.envstruc->speed);
2812 }
2813 
triggerEnvelopes(TModuleChannel * chnInf)2814 void PlayerIT::triggerEnvelopes(TModuleChannel* chnInf)
2815 {
2816 	const mp_sint32 smp = chnInf->getSmp();
2817 	const mp_sint32 ins = chnInf->getIns();
2818 
2819 	bool insEnv = (module->instr[ins-1].flags & TXMInstrument::IF_ITENVELOPES);
2820 
2821 	mp_uword e = insEnv ? module->instr[ins-1].venvnum : module->smp[smp].venvnum;
2822 	if (e)
2823 		triggerEnvelope(chnInf->getVenv(), module->venvs[e-1]);
2824 	else
2825 		chnInf->getVenv().envstruc=NULL;
2826 
2827 	e = insEnv ? module->instr[ins-1].penvnum : module->smp[smp].penvnum;
2828 	if (e)
2829 		triggerEnvelope(chnInf->getPenv(), module->penvs[e-1]);
2830 	else
2831 		chnInf->getPenv().envstruc=NULL;
2832 
2833 	e = insEnv ? module->instr[ins-1].fenvnum : module->smp[smp].fenvnum;
2834 	if (e)
2835 		triggerEnvelope(chnInf->getFenv(), module->fenvs[e-1]);
2836 	else
2837 		chnInf->getFenv().envstruc=NULL;
2838 
2839 	e = insEnv ? module->instr[ins-1].vibenvnum : module->smp[smp].vibenvnum;
2840 	if (e)
2841 		triggerEnvelope(chnInf->getVibenv(), module->vibenvs[e-1]);
2842 	else
2843 		chnInf->getVibenv().envstruc=NULL;
2844 
2845 	e = insEnv ? module->instr[ins-1].pitchenvnum : module->smp[smp].pitchenvnum;
2846 	if (e)
2847 		triggerEnvelope(chnInf->getPitchenv(), module->pitchenvs[e-1]);
2848 	else
2849 		chnInf->getPitchenv().envstruc=NULL;
2850 }
2851 
triggerAutovibrato(TModuleChannel * chnInf)2852 void PlayerIT::triggerAutovibrato(TModuleChannel* chnInf)
2853 {
2854 	const mp_sint32 smp = chnInf->getSmp();
2855 
2856 	if (module->smp[smp].vibdepth&&module->smp[smp].vibrate)
2857 	{
2858 		//chnInf->avibused=1;
2859 		chnInf->setAvibused((module->smp[smp].vibtype+1) | ((module->smp[smp].flags & 16) ? 128 : 0));
2860 		chnInf->setAvibdepth(module->smp[smp].vibdepth);
2861 		chnInf->setAvibspd(module->smp[smp].vibrate);
2862 		chnInf->setAvibswcnt(0);
2863 		chnInf->setAvibsweep(module->smp[smp].vibsweep);
2864 	}
2865 	else chnInf->setAvibused(0);
2866 }
2867 
triggerInstrumentFX(TModuleChannel * chnInf,bool triggerEnv)2868 void PlayerIT::triggerInstrumentFX(TModuleChannel* chnInf, bool triggerEnv/* = true*/)
2869 {
2870 	const mp_sint32 smp = chnInf->getSmp();
2871 	const mp_sint32 ins = chnInf->getIns();
2872 
2873 	if (smp != -1)
2874 	{
2875 		if (triggerEnv)
2876 			triggerEnvelopes(chnInf);
2877 		triggerAutovibrato(chnInf);
2878 
2879 		chnInf->setFadevolstart(65536);
2880 		// Check for IT style fadeout (instrument rather than sample based)
2881 		if (ins && (module->instr[ins-1].flags & TXMInstrument::IF_ITFADEOUT))
2882 			chnInf->setFadevolstep(module->instr[ins-1].volfade);
2883 		else
2884 			chnInf->setFadevolstep(module->smp[smp].volfade);
2885 	}
2886 }
2887 
2888 #define INVALIDVALUE -12345678
2889 
progressRow()2890 void PlayerIT::progressRow()
2891 {
2892 	mp_sint32 slotsize = (numEffects*2)+2;
2893 
2894 	TXMPattern* pattern = &module->phead[patternIndex];
2895 
2896 	mp_ubyte *row = pattern->patternData+
2897 						 (pattern->channum*slotsize*rowcnt);
2898 
2899 	/*if (rowcnt == 3)
2900 	{
2901 		int i = 0;
2902 		i++;
2903 		i--;
2904 	}*/
2905 
2906 	//for (mp_sint32 chn=4;chn<5;chn++) {
2907 	for (mp_sint32 chn=0;chn<numChannels;chn++) {
2908 
2909 		if ((mp_sint32)attick[chn]==ticker && ticker < tickSpeed) {
2910 			TModuleChannel *chnInf = &chninfo[chn];
2911 
2912 			mp_sint32 pp = slotsize*chn;
2913 			mp_sint32 note = chnInf->currentnote = row[pp];
2914 			mp_sint32 i    = row[pp+1];
2915 
2916 			bool noteporta = false;
2917 			bool notedelay = false;
2918 			bool forcefade = false;
2919 
2920 			mp_sint32 oldIns = chnInf->getIns();
2921 			mp_sint32 oldSmp = chnInf->getSmp();
2922 
2923 			// Effect preprocessor & get effect + operand from interleaved pattern data
2924 			mp_sint32 effcnt, finetune = 0x7FFFFFFF;
2925 			for (effcnt = 0; effcnt < numEffects; effcnt++) {
2926 				chnInf->eff[effcnt] = row[(pp+2)+(effcnt*2)];
2927 				chnInf->eop[effcnt] = row[(pp+2)+(effcnt*2+1)];
2928 				switch (chnInf->eff[effcnt])
2929 				{
2930 					// We need to know if we process the note as new note or or portamento destination period
2931 					case 0x03:
2932 					case 0x05:
2933 						noteporta = true;
2934 						break;
2935 					// nasty FT2 "feature"
2936 					// if there is a set volume in the first column
2937 					// and note == NOTE_OFF set a flag for later use
2938 					case 0x0C:
2939 					{
2940 						if (playModeFT2 &&
2941 							(note == XModule::NOTE_OFF || (effcnt == 0 && numEffects == 2 && chnInf->eff[effcnt+1] == 0x14)))
2942 						{
2943 							forcefade = true;
2944 						}
2945 						break;
2946 					}
2947 					// XM key off at tick with tick operand == 0 is like normal key off
2948 					case 0x14:
2949 						if (chnInf->eop[effcnt] == 0)
2950 							note = XModule::NOTE_OFF;
2951 						break;
2952 					// set finetune will override the instrument setting
2953 					case 0x35:
2954 						finetune = XModule::modfinetunes[playModeFT2 ? ((chnInf->eop[effcnt] - 8) & 0xF) : (chnInf->eop[effcnt] & 0xF)];
2955 						break;
2956 					// note delay without note retriggers last bnote
2957 					case 0x3d:
2958 						notedelay = true;
2959 						if (!note && chnInf->eop[effcnt] && playModeFT2)
2960 							note = chnInf->lastnoportanote;
2961 						break;
2962 				}
2963 			}
2964 
2965 			// Temporary placeholders, those will be applied after
2966 			// having allocated a new virtual channel
2967 			mp_sint32 finalNote			= chnInf->getNote();
2968 			mp_sint32 finalIns			= chnInf->getIns();
2969 			mp_uword  finalInsflags		= chnInf->getInsflags();
2970 			mp_sint32 finalSmp			= chnInf->getSmp();
2971 			mp_sint32 finalPeriod		= chnInf->getPer();
2972 			mp_sint32 finalFreqAdjust	= chnInf->getFreqadjust();
2973 			mp_sint32 finalRelnote		= chnInf->getRelnote();
2974 			mp_sint32 finalFinetune		= chnInf->getFinetune();
2975 			mp_sint32 finalVolume		= chnInf->getVolume();
2976 
2977 			bool stopChannel			= false;
2978 
2979 			// Check new instrument settings only if valid note or no note at all
2980 			if (i && note <= XModule::NOTE_LAST) {
2981 				// valid sample?
2982 				bool invalidIns = true;
2983 				bool invalidSmp = true;
2984 
2985 				// invalid instrument
2986 				if (i <= module->header.insnum && module->instr[i-1].samp)
2987 					invalidIns = false;
2988 				// invalid sample
2989 				if (module->instr[i-1].samp && module->instr[i-1].snum[0] != -1)
2990 					invalidSmp = false;
2991 
2992 				if (!invalidIns) // valid sample
2993 					finalIns = i;
2994 				else if (note) // invalid sample
2995 				{
2996 					// cut means stop sample in FT2
2997 					if (!newInsPTFlag && !newInsST3Flag && !noteporta)
2998 					{
2999 						finalSmp = -1;
3000 						finalIns = 0;
3001 						stopChannel = true;
3002 					}
3003 				}
3004 
3005 				// protracker sample cut when invalid instrument is triggered
3006 				if (newInsPTFlag)
3007 				{
3008 					if (!note)
3009 					{
3010 						if (invalidSmp)
3011 						{
3012 							finalSmp = -1;
3013 							finalIns = 0;
3014 							finalVolume = 0; // cut means: volume to zero (no stop sample)
3015 						}
3016 						else
3017 						{
3018 							finalSmp = module->instr[i-1].snum[0];
3019 						}
3020 					}
3021 					else
3022 					{
3023 						if (invalidSmp)
3024 						{
3025 							finalSmp = -1;
3026 							finalIns = 0;
3027 							finalVolume = 0; // cut means: volume to zero (no stop sample)
3028 							// NOT sure!!!
3029 							//stopSample(chn);
3030 						}
3031 					}
3032 				}
3033 				// screamtracker continues playing when invalid instrument is triggered
3034 				// applies new volume when instrument only is triggered
3035 				else if (newInsST3Flag)
3036 				{
3037 					if (!note)
3038 					{
3039 						if (!invalidSmp)
3040 						{
3041 							finalSmp = module->instr[i-1].snum[0];
3042 						}
3043 						// completely invalid instrument without note, does nothing at all
3044 						else
3045 						{
3046 							i = 0;
3047 						}
3048 					}
3049 				}
3050 			}
3051 
3052 			chnInf->validnote = true;
3053 			if (note && note < XModule::NOTE_OFF)
3054 			{
3055 				const mp_sint32 ins = finalIns;
3056 				if (ins)
3057 				{
3058 					finalSmp = module->instr[ins-1].snum[note-1];
3059 					if ((module->instr[ins-1].flags & 1) &&
3060 						module->instr[ins-1].notemap[note-1] != 0xFF)
3061 					{
3062 						chnInf->currentnote = note = module->instr[ins-1].notemap[note-1] + 1;
3063 					}
3064 
3065 					// if Impulse Tracker instrument, we only apply the sample finetune / relnote when
3066 					// there is a note AND an instrument set, otherwise keep settings
3067 					if (!(module->instr[ins-1].flags & 1) || ((module->instr[ins-1].flags & 1) && i))
3068 					{
3069 						// invalid sample entry?
3070 						// Only apply new fintune / relative note number when not doing portamento
3071 						mp_sint32 smp = finalSmp;
3072 						if (smp != -1 && !noteporta) {
3073 							mp_sint32 finalNote = note + (mp_sint32)module->smp[smp].relnote;
3074 							// limit to upper boundary is enabled (FT2)
3075 							if (module->header.uppernotebound)
3076 							{
3077 								// Within current note range?
3078 								if (finalNote >= 1 && finalNote <= (mp_sint32)module->header.uppernotebound)
3079 								{
3080 									finalFinetune = (finetune != 0x7FFFFFFF ? finetune : module->smp[smp].finetune);
3081 									finalRelnote = module->smp[smp].relnote;
3082 									finalFreqAdjust = module->smp[smp].freqadjust;
3083 								}
3084 								// This is not a valid note
3085 								else
3086 								{
3087 									chnInf->validnote = false;
3088 									note = finalNote;
3089 								}
3090 							}
3091 							else
3092 							{
3093 								finalFinetune = (finetune != 0x7FFFFFFF ? finetune : module->smp[smp].finetune);
3094 								finalRelnote = module->smp[smp].relnote;
3095 								finalFreqAdjust = module->smp[smp].freqadjust;
3096 							}
3097 
3098 						}
3099 					}
3100 				}
3101 
3102 				mp_sint32 relnote = finalRelnote;
3103 				mp_sint32 finetune = finalFinetune;
3104 
3105 				// If this is not a note portamento
3106 				// and a valid note => keep that note and calculate new period
3107 				if (!noteporta) {
3108 					finalNote = chnInf->lastnoportanote = note;
3109 					finalPeriod = getperiod(note,relnote,finetune);
3110 					// if there is a valid note => destroy portamento to note memory when playing an S3M(?)
3111 					if (/*newInsPTFlag||*/newInsST3Flag)
3112 					{
3113 						chnInf->destnote=0;
3114 						chnInf->destper=0;
3115 					}
3116 				}
3117 				// If this is a note portamento keep destination's note + period
3118 				else  {
3119 					// if a note delay is happening while the portamento is set, AND we don't have a note (?)
3120 					// we restore the original period, but the destination period keeps set
3121 					if (playModeFT2 && notedelay && !chnInf->currentnote)
3122 						finalPeriod=getperiod(note,relnote,finetune);
3123 					else
3124 					{
3125 						chnInf->lastnoportanote=finalNote;
3126 						chnInf->destnote=finalNote=note;
3127 						chnInf->destper=getperiod(note,relnote,finetune);
3128 					}
3129 				}
3130 
3131 				// If this has not been a valid note, do not trigger it
3132 				if (!chnInf->validnote)
3133 					note = 0;
3134 			}
3135 
3136 			// take over instrument flags (NNA/DCT/DCA)
3137 			if ((i == finalIns) && finalIns)
3138 				finalInsflags = module->instr[finalIns-1].flags;
3139 
3140 			// --- this is the place to allocate new virtual channels ---
3141 			if (finalSmp != -1 && !noteporta &&
3142 				note && note < XModule::NOTE_OFF)
3143 			{
3144 				TNNATriggerInfo triggerInfo;
3145 				triggerInfo.ins = i;
3146 				triggerInfo.smp = finalSmp;
3147 				triggerInfo.note = note;
3148 				if (!handleNNAs(chnInf, triggerInfo))
3149 					continue;
3150 			}
3151 
3152 			// apply new state to new channel
3153 			if (finalNote != chnInf->getNote())
3154 			{
3155 				chnInf->setNote(finalNote);
3156 			}
3157 			if (finalIns != chnInf->getIns())
3158 			{
3159 				chnInf->setIns(finalIns);
3160 			}
3161 			if (finalInsflags != chnInf->getInsflags())
3162 			{
3163 				chnInf->setInsflags(finalInsflags);
3164 			}
3165 			if (finalSmp != chnInf->getSmp())
3166 			{
3167 				chnInf->setSmp(finalSmp);
3168 			}
3169 			if (finalPeriod != chnInf->getPer())
3170 			{
3171 				chnInf->setPer(finalPeriod);
3172 				chnInf->adjustVibratoPer();
3173 			}
3174 			if (finalFreqAdjust	!= chnInf->getFreqadjust())
3175 			{
3176 				chnInf->setFreqadjust(finalFreqAdjust);
3177 			}
3178 			if (finalRelnote != chnInf->getRelnote())
3179 			{
3180 				chnInf->setRelnote(finalRelnote);
3181 			}
3182 			if (finalFinetune != chnInf->getFinetune())
3183 			{
3184 				chnInf->setFinetune(finalFinetune);
3185 			}
3186 			if (finalVolume != chnInf->getVol())
3187 			{
3188 				chnInf->setVol(finalVolume);
3189 				chnInf->adjustTremoloTremorVol();
3190 			}
3191 			if (stopChannel && chnInf->hasVchn())
3192 			{
3193 				stopSample(chnInf->getPlaybackChannelIndex());
3194 			}
3195 
3196 			// man this FT2 bug emulation starts getting on my nerves:
3197 			// only take new instrument of there is no note porta
3198 			if (playModeFT2 && i &&
3199 				(noteporta || !chnInf->validnote))
3200 			{
3201 				i = oldIns;
3202 				chnInf->setIns(i);
3203 				chnInf->setSmp(oldSmp);
3204 			}
3205 
3206 			// when we have a new instrument we apply the settings for this instrument
3207 			if (i && chnInf->getSmp() != -1 && note < XModule::NOTE_OFF)
3208 			{
3209 				if (module->instr[i-1].flags & TXMInstrument::IF_ITGOBALINSVOL)
3210 					chnInf->setInsMasterVol(module->instr[i-1].res);
3211 				else
3212 					chnInf->setInsMasterVol(255);
3213 
3214 				mp_sint32 smp = chnInf->getSmp();
3215 
3216 				if ((module->smp[smp].flags&1))
3217 				{
3218 					chnInf->setVol(module->smp[smp].vol);
3219 					chnInf->adjustTremoloTremorVol();
3220 				}
3221 				if (playModeFT2 &&
3222 					(module->smp[smp].flags&2))
3223 					chnInf->setPan(module->smp[smp].pan);
3224 				if ((module->smp[smp].flags&4))
3225 					chnInf->setMasterVol(module->smp[smp].vol);
3226 				if ((module->smp[smp].flags&8))
3227 					chnInf->setSmpMasterVol(module->smp[smp].res);
3228 				else
3229 					chnInf->setSmpMasterVol(255);
3230 
3231 				chnInf->setCutoff(module->instr[i-1].ifc);
3232 				chnInf->setResonance(module->instr[i-1].ifr);
3233 
3234 				if (noteporta && (module->header.flags & XModule::MODULE_ITNEWGXX))
3235 					triggerInstrumentFX(chnInf, false);
3236 				else
3237 					triggerInstrumentFX(chnInf);
3238 
3239 				// reset vibrato/tremolo/tremor/retrig counters
3240 				for (effcnt=0;effcnt<numEffects;effcnt++)
3241 					chnInf->vibpos[effcnt] = chnInf->tremorcnt[effcnt] = chnInf->trmpos[effcnt] = chnInf->panbrellopos[effcnt] = chnInf->retrigcounterRxx[effcnt] = 0;
3242 
3243 				if (playModePT)
3244 					chnInf->smpoffs = 0;
3245 
3246 				chnInf->setKeyon(true);
3247 			}
3248 
3249 			// ------ 11/05/05: it seems that note off commands are processed BEFORE effect commands
3250 			// S3M style keyoff:
3251 			// sample is stopped
3252 			if (note == XModule::NOTE_CUT) {
3253 				note=0;
3254 				if (chnInf->getVenv().envstruc!=NULL) {
3255 					if (!chnInf->getVenv().isEnabled())
3256 					{
3257 						chnInf->setVol(0);
3258 						chnInf->adjustTremoloTremorVol();
3259 						if (chnInf->getPlaybackChannelIndex() >= 0)
3260 							stopSample(chnInf->getPlaybackChannelIndex());
3261 					}
3262 				}
3263 				else {
3264 					chnInf->setVol(0);
3265 					chnInf->adjustTremoloTremorVol();
3266 					if (chnInf->getPlaybackChannelIndex() >= 0)
3267 						stopSample(chnInf->getPlaybackChannelIndex());
3268 				}
3269 			}
3270 			// XM/IT style keyoff:
3271 			else if (note == XModule::NOTE_OFF)
3272 			{
3273 				note = 0;
3274 				handleNoteOFF(chnInf->chnstat());
3275 			}
3276 
3277 			chnInf->hasSetVolume = false;
3278 			for (effcnt=0;effcnt<numEffects;effcnt++) {
3279 				// MTM hack
3280 				// sample offset without note seems to trigger last note
3281 				if (chnInf->eff[effcnt] == 0x09 && !note && module->getType() == XModule::ModuleType_MTM)
3282 				{
3283 					note = chnInf->getNote();
3284 				}
3285 				doEffect(chnInf, effcnt);
3286 			} // for
3287 
3288 			if (note)
3289 			{
3290 				if (note <= XModule::NOTE_OFF)
3291 				{
3292 					if (!noteporta)
3293 					{
3294 						playInstrument(chnInf);
3295 					}
3296 					else if (oldPTInsChangeFlag &&
3297 							 newInsPTFlag &&
3298 							 noteporta &&
3299 							 i &&
3300 							 chnInf->getSmp() != -1 &&
3301 							 chnInf->getNote())
3302 					{
3303 						playInstrument(chnInf, true);
3304 					}
3305 
3306 				}
3307 
3308 			} // note
3309 			else if (oldPTInsChangeFlag &&
3310 					 newInsPTFlag &&
3311 					 i &&
3312 					 chnInf->getNote() &&
3313 					 chnInf->getPer())
3314 			{
3315 				playInstrument(chnInf, true);
3316 			}
3317 
3318 		}
3319 
3320 	}
3321 
3322 }
3323 
3324 
3325 
update()3326 void PlayerIT::update()
3327 {
3328 	mp_sint32 c;
3329 
3330 	TVirtualChannel* chn = vchninfo;
3331 	const mp_sint32 curMaxVirChannels = this->curMaxVirChannels;
3332 	for (c = 0; c < curMaxVirChannels; c++, chn++)
3333 	{
3334 		if (!chn->getActive())
3335 			continue;
3336 
3337 		if (chn->isFlagSet(CHANNEL_FLAGS_UPDATE_IGNORE))
3338 			continue;
3339 
3340 		const mp_sint32 ins = chn->getIns();
3341 		bool ITEnvelopes = (ins && ins <= module->header.insnum) ? (module->instr[ins-1].flags & TXMInstrument::IF_ITENVELOPES) : false;
3342 
3343 		mp_sint32 dfs = chn->getFlags() & CHANNEL_FLAGS_DFS;
3344 		mp_sint32 dvs = chn->getFlags() & CHANNEL_FLAGS_DVS;
3345 		mp_sint32 dps = chn->getFlags() & CHANNEL_FLAGS_DPS;
3346 
3347 		if (chn->getPeriod() && !dfs)
3348 			setFreq(c,getFinalFreq(chn->chnstat(),getFinalPeriod(chn->chnstat(),chn->getPeriod())));
3349 
3350 		if (!dvs)
3351 			setVol(c,getFinalVolume(chn->chnstat(), chn->getVolume(), mainVolume));
3352 
3353 		if (!dps)
3354 			setPan(c,getFinalPanning(chn->chnstat(),chn->getPan()));
3355 
3356 		if (chn->getVenv().envstruc != NULL &&
3357 			!chn->getVenv().envstruc->speed)
3358 		{
3359 			prenvelope(&chn->getVenv(), chn->getKeyon(), ITEnvelopes);
3360 			if (ins && ins <= module->header.insnum && (module->instr[ins-1].flags & TXMInstrument::IF_ITFADEOUT))
3361 			{
3362 				if (chn->getVenv().finished(chn->getKeyon()) &&
3363 					!chn->getFadeout())
3364 				{
3365 					chn->setFadeout(true);
3366 				}
3367 			}
3368 		}
3369 
3370 		// IT filter processing
3371 		mp_sint32 cutoff = MP_INVALID_VALUE;
3372 		if (chn->getCutoff() >= 128)
3373 			cutoff = chn->getCutoff() - 128;
3374 
3375 		mp_sint32 resonance = 0;
3376 		if (chn->getResonance() >= 128)
3377 			resonance = chn->getResonance() - 128;
3378 
3379 		setFilterAttributes(c, getFinalCutoff(chn->chnstat(), cutoff), resonance);
3380 
3381 		if (chn->getPenv().envstruc != NULL &&
3382 			!chn->getPenv().envstruc->speed)
3383 		{
3384 			prenvelope(&chn->getPenv(), chn->getKeyon(), ITEnvelopes);
3385 		}
3386 
3387 		if (chn->getFenv().envstruc != NULL &&
3388 			!chn->getFenv().envstruc->speed)
3389 		{
3390 			prenvelope(&chn->getFenv(), chn->getKeyon(), ITEnvelopes);
3391 		}
3392 
3393 		if (chn->getVibenv().envstruc != NULL &&
3394 			!chn->getVibenv().envstruc->speed)
3395 		{
3396 			prenvelope(&chn->getVibenv(), chn->getKeyon(), ITEnvelopes);
3397 		}
3398 
3399 		if (chn->getPitchenv().envstruc != NULL &&
3400 			!chn->getPitchenv().envstruc->speed)
3401 		{
3402 			prenvelope(&chn->getPitchenv(), chn->getKeyon(), ITEnvelopes);
3403 		}
3404 
3405 		if (ins && ins <= module->header.insnum)
3406 		{
3407 			// IT style fadeout also works without active envelope
3408 			if ((module->instr[ins-1].flags & TXMInstrument::IF_ITFADEOUT) &&
3409 				chn->getFadeout())
3410 			{
3411 				chn->decFadevolstart();
3412 			}
3413 			// XM style fadeout works only with key off
3414 			else if (!chn->getKeyon())
3415 			{
3416 				chn->decFadevolstart();
3417 			}
3418 		}
3419 
3420 		if (chn->getAvibused())
3421 		{
3422 			chn->avibAdvance();
3423 		}
3424 	}
3425 
3426 	adjustVirtualChannels();
3427 
3428 }
3429 
updateBPMIndependent()3430 void PlayerIT::updateBPMIndependent()
3431 {
3432 	mp_int64 dummy;
3433 
3434 	TVirtualChannel* chn = vchninfo;
3435 	const mp_sint32 curMaxVirChannels = this->curMaxVirChannels;
3436 	for (mp_sint32 c = 0; c < curMaxVirChannels; c++,chn++)
3437 	{
3438 		TVirtualChannel* chn = &vchninfo[c];
3439 
3440 		if (!chn->getActive())
3441 			continue;
3442 
3443 		if (chn->isFlagSet(CHANNEL_FLAGS_UPDATE_IGNORE))
3444 			continue;
3445 
3446 		const mp_sint32 ins = chn->getIns();
3447 		bool ITEnvelopes = (ins && ins <= module->header.insnum) ? (module->instr[ins-1].flags & TXMInstrument::IF_ITENVELOPES) : false;
3448 
3449 		mp_sint32 dfs = chn->getFlags() & CHANNEL_FLAGS_DFS, dvs = chn->getFlags() & CHANNEL_FLAGS_DVS;
3450 
3451 		// Volume envelope
3452 		if (chn->getVenv().envstruc != NULL &&
3453 			chn->getVenv().envstruc->speed)
3454 		{
3455 			dummy = (mp_int64)chn->getVenv().bpmCounter;
3456 			dummy+=(mp_int64)chn->getVenv().bpmAdder;
3457 			chn->getVenv().bpmCounter = (mp_sint32)dummy;
3458 			// check overflow-carry
3459 			if (dummy>>32)
3460 			{
3461 				prenvelope(&chn->getVenv(), chn->getKeyon(), ITEnvelopes);
3462 				if (!dvs)
3463 					setVol(c,getFinalVolume(chn->chnstat(), chn->getVolume(), mainVolume));
3464 			}
3465 		}
3466 
3467 		// Panning envelope
3468 		if (chn->getPenv().envstruc != NULL &&
3469 			chn->getPenv().envstruc->speed)
3470 		{
3471 			dummy = (mp_int64)chn->getPenv().bpmCounter;
3472 			dummy+=(mp_int64)chn->getPenv().bpmAdder;
3473 			chn->getPenv().bpmCounter = (mp_sint32)dummy;
3474 			// check overflow-carry
3475 			if (dummy>>32)
3476 			{
3477 				prenvelope(&chn->getPenv(), chn->getKeyon(), ITEnvelopes);
3478 				setPan(c,getFinalPanning(chn->chnstat(),chn->getPan()));
3479 			}
3480 		}
3481 
3482 		// Frequency envelope: Digitracker MDL
3483 		if (chn->getFenv().envstruc != NULL &&
3484 			chn->getFenv().envstruc->speed)
3485 		{
3486 			dummy = (mp_int64)chn->getFenv().bpmCounter;
3487 			dummy+=(mp_int64)chn->getFenv().bpmAdder;
3488 			chn->getFenv().bpmCounter = (mp_sint32)dummy;
3489 			// check overflow-carry
3490 			if (dummy>>32)
3491 			{
3492 				prenvelope(&chn->getFenv(), chn->getKeyon(), ITEnvelopes);
3493 				if (chn->getPeriod()&&(!dfs))
3494 					setFreq(c,getFinalFreq(chn->chnstat(),getFinalPeriod(chn->chnstat(),chn->getPeriod())));
3495 			}
3496 		}
3497 
3498 		// Vibrato envelope: Velvet Studio AMS
3499 		if (chn->getVibenv().envstruc != NULL &&
3500 			chn->getVibenv().envstruc->speed)
3501 		{
3502 			dummy = (mp_int64)chn->getVibenv().bpmCounter;
3503 			dummy+=(mp_int64)chn->getVibenv().bpmAdder;
3504 			chn->getVibenv().bpmCounter = (mp_sint32)dummy;
3505 			// check overflow-carry
3506 			if (dummy>>32)
3507 			{
3508 				prenvelope(&chn->getVibenv(), chn->getKeyon(), ITEnvelopes);
3509 				if (chn->getPeriod()&&(!dfs))
3510 					setFreq(c,getFinalFreq(chn->chnstat(),getFinalPeriod(chn->chnstat(),chn->getPeriod())));
3511 			}
3512 		}
3513 
3514 		// Pitch envelope: Impulse Tracker
3515 		if (chn->getPitchenv().envstruc != NULL &&
3516 			chn->getPitchenv().envstruc->speed)
3517 		{
3518 			dummy = (mp_int64)chn->getPitchenv().bpmCounter;
3519 			dummy+=(mp_int64)chn->getPitchenv().bpmAdder;
3520 			chn->getPitchenv().bpmCounter = (mp_sint32)dummy;
3521 			// check overflow-carry
3522 			if (dummy>>32)
3523 			{
3524 				prenvelope(&chn->getPitchenv(), chn->getKeyon(), ITEnvelopes);
3525 				if (chn->getPeriod()&&(!dfs))
3526 					setFreq(c,getFinalFreq(chn->chnstat(),getFinalPeriod(chn->chnstat(),chn->getPeriod())));
3527 			}
3528 		}
3529 
3530 	}
3531 
3532 	adjustVirtualChannels();
3533 
3534 }
3535 
setNewPosition(mp_sint32 poscnt)3536 void inline PlayerIT::setNewPosition(mp_sint32 poscnt)
3537 {
3538 	if (poscnt == this->poscnt)
3539 		return;
3540 
3541 	if (poscnt>=module->header.ordnum)
3542 		poscnt=module->header.restart;
3543 
3544 	// reset looping flags
3545 	RESET_ALL_LOOPING
3546 
3547 	lastUnvisitedPos = this->poscnt;
3548 
3549 	this->poscnt = poscnt;
3550 }
3551 
tickhandler()3552 void PlayerIT::tickhandler()
3553 {
3554 	mp_sint32 maxTicks;
3555 
3556 	if (!idle)
3557 	{
3558 		// Important! Without this, the different playmodes will not be recognized properly
3559 		updatePlayModeFlags();
3560 
3561 		// sanity check 1
3562 		if (patternIndexToPlay == -1 && poscnt >= module->header.ordnum)
3563 		{
3564 			halt();
3565 			return;
3566 		}
3567 
3568 		// Play special pattern?
3569 		if (patternIndexToPlay == -1)
3570 			patternIndex = module->header.ord[poscnt];
3571 		else
3572 			patternIndex = patternIndexToPlay;
3573 
3574 		TXMPattern* pattern = &module->phead[patternIndex];
3575 
3576 		if (pattern->patternData == NULL)
3577 		{
3578 			halt();
3579 			return;
3580 		}
3581 
3582 		// sanity check 2 :)
3583 		if (rowcnt >= pattern->rows)
3584 		{
3585 			if (patternIndexToPlay == -1)
3586 			{
3587 				//rowcnt = 0;
3588 				ticker = 0;
3589 				goto nextrow;
3590 			}
3591 			else
3592 			{
3593 				//halt();
3594 				//return;
3595 				rowcnt = 0;
3596 				ticker = 0;
3597 			}
3598 		}
3599 
3600 		numEffects = pattern->effnum;
3601 		numChannels = pattern->channum <= module->header.channum ? pattern->channum : module->header.channum;
3602 
3603 		mp_sint32 c;
3604 
3605 		if (ticker == 0)
3606 		{
3607 
3608 			// Keep track of visited rows
3609 			mp_sint32 absolutePos = poscnt*256+rowcnt;
3610 			if (isRowVisited(absolutePos) && !repeat)
3611 			{
3612 				// pattern loop active?
3613 				bool b = false;
3614 				for (c=0;c<numChannels;c++)
3615 				{
3616 					if (chninfo[c].isLooping && chninfo[c].loopingValidPosition == poscnt)
3617 					{
3618 						b = true;
3619 						break;
3620 					}
3621 				}
3622 
3623 				if (!b)
3624 				{
3625 					halt();
3626 					return;
3627 				}
3628 			}
3629 			else
3630 			{
3631 				visitRow(absolutePos);
3632 			}
3633 
3634 			pbreak = pbreakpos = pbreakPriority = pjump = pjumppos = pjumprow = pjumpPriority = 0;
3635 			// sample offset 0
3636 			if (!playModePT)
3637 			{
3638 				for (c=0;c<numChannels;c++)
3639 					chninfo[c].smpoffs = 0;
3640 			}
3641 			// noteslot will be processed at tick 0
3642 			memset(attick,0,sizeof(mp_ubyte)*numChannels);
3643 
3644 			// search for note delays
3645 			mp_sint32 slotsize = (numEffects*2)+2;
3646 
3647 			mp_ubyte *row = pattern->patternData+(pattern->channum*slotsize*rowcnt);
3648 
3649 			// process high priority effects in advance to other effects
3650 			mp_ubyte* slot = row;
3651 
3652 			for (c=0;c<numModuleChannels;c++)
3653 				chninfo[c].channelIndex = c;
3654 
3655 			for (c=0;c<numChannels;c++)
3656 			{
3657 				chninfo[c].setFlags(0);
3658 
3659 				for (mp_sint32 effcnt=0;effcnt<numEffects;effcnt++)
3660 				{
3661 					chninfo[c].eff[effcnt] = 0;
3662 					chninfo[c].eop[effcnt] = 0;
3663 
3664 					if (slot[2+(effcnt*2)] == 0x04) chninfo[c].setFlag(CHANNEL_FLAGS_DFS);
3665 					else if (slot[2+(effcnt*2)] == 0x4A) chninfo[c].setFlag(CHANNEL_FLAGS_DFS);
3666 					else if (slot[2+(effcnt*2)] == 0x06) chninfo[c].setFlag(CHANNEL_FLAGS_DFS);
3667 					else if (slot[2+(effcnt*2)] == 0x20) chninfo[c].setFlag(CHANNEL_FLAGS_DFS); // normal arpeggio
3668 					else if (slot[2+(effcnt*2)] == 0x56) chninfo[c].setFlag(CHANNEL_FLAGS_DFS); // oktalyzer arpeggio I
3669 					else if (slot[2+(effcnt*2)] == 0x57) chninfo[c].setFlag(CHANNEL_FLAGS_DFS); // oktalyzer arpeggio II
3670 					else if (slot[2+(effcnt*2)] == 0x58) chninfo[c].setFlag(CHANNEL_FLAGS_DFS); // oktalyzer arpeggio III
3671 					else if (slot[2+(effcnt*2)] == 0x07) chninfo[c].setFlag(CHANNEL_FLAGS_DVS); // Tremolo
3672 					else if (slot[2+(effcnt*2)] == 0x1D) chninfo[c].setFlag(CHANNEL_FLAGS_DVS); // Tremor
3673 					else if (slot[2+(effcnt*2)] == 0x5C) chninfo[c].setFlag(CHANNEL_FLAGS_DPS); // Panbrello
3674 
3675 					else if (slot[2+(effcnt*2)] == 0x3D)
3676 					{
3677 						// found note delay: noteslot will be processed at a later tick
3678 						attick[c] = slot[2+(effcnt*2)+1];
3679 					}
3680 					// set speed in advance also,
3681 					// in order to correctly implement note delay
3682 					else if (slot[2+(effcnt*2)] == 0xf &&		// protracker set speed/bpm
3683 						slot[2+(effcnt*2)+1] &&
3684 						slot[2+(effcnt*2)+1] < 32)		// set tickspeed not BPM
3685 					{
3686 						tickSpeed = slot[2+(effcnt*2)+1];
3687 					}
3688 					else if (slot[2+(effcnt*2)] == 0x1c &&	//  S3M/MDL/... set speed
3689 						slot[2+(effcnt*2)+1])			// valid set speed?
3690 						tickSpeed = slot[2+(effcnt*2)+1];
3691 				}
3692 
3693 				slot+=slotsize;
3694 			}
3695 
3696 		}
3697 
3698 		progressRow();
3699 
3700 		doTickeffects();
3701 
3702 		ticker++;
3703 
3704 		maxTicks = tickSpeed;
3705 		if (patDelay)
3706 			maxTicks = patDelayCount;
3707 
3708 		if (ticker>=maxTicks)
3709 		{
3710 			if (patDelay)
3711 				patDelay = false;
3712 
3713 			// reset ticker
3714 			ticker=0;
3715 
3716 			// if we're told to play this row only, we will stop now
3717 			// and neither process any of those pattern jump/repeat stuff
3718 			if (playOneRowOnly)
3719 			{
3720 				BPMCounter = adder = 0;
3721 				return;
3722 			}
3723 
3724 			if (patternIndexToPlay == -1)
3725 			{
3726 
3727 				// break pattern?
3728 				if (pbreak&&(poscnt<(module->header.ordnum-1)))
3729 				{
3730 					if (!pjump || (pjump && pjumpPriority > pbreakPriority))
3731 						setNewPosition(poscnt+1);
3732 					rowcnt=pbreakpos-1;
3733 					startNextRow = -1;
3734 				}
3735 				else if (pbreak&&(poscnt==(module->header.ordnum-1)))
3736 				{
3737 					// Pattern break on the last order? Break to restart position
3738 					if (!pjump || (pjump && pjumpPriority > pbreakPriority))
3739 						setNewPosition(module->header.restart);
3740 					rowcnt=pbreakpos-1;
3741 					startNextRow = -1;
3742 				}
3743 
3744 				// pattern jump?
3745 				if (pjump)
3746 				{
3747 					if (!pbreak || (pbreak && pjumpPriority > pbreakPriority))
3748 						rowcnt = pjumprow-1;
3749 					setNewPosition(pjumppos);
3750 					startNextRow = -1;
3751 				}
3752 
3753 				// it could be that our position has changed because
3754 				// of position jumps, so make sure we're getting the real position here
3755 				patternIndex = module->header.ord[poscnt];
3756 			}
3757 			// We have one pattern to play
3758 			else
3759 			{
3760 				// Position jump occurred and repeating is allowed, start again
3761 				if (pjump || pbreak)
3762 				{
3763 					rowcnt = -1;
3764 					startNextRow = -1;
3765 				}
3766 				//RESETLOOPING // macro
3767 			}
3768 
3769 			// handle loop
3770 			for (c=0;c<numChannels;c++)
3771 			{
3772 				// pattern loop? nesting doesn't work yet
3773 				if (chninfo[c].execloop)
3774 				{
3775 					rowcnt = chninfo[c].loopstart-1;
3776 					chninfo[c].execloop = 0;
3777 					chninfo[c].isLooping = true;
3778 				}
3779 			}
3780 
3781 			// next row
3782 			rowcnt++;
3783 nextrow:
3784 			synccnt++;
3785 
3786 			// reached end of pattern?
3787 			if (rowcnt>=module->phead[patternIndex].rows)
3788 			{
3789 				// start at row 0?
3790 				if (startNextRow != -1)
3791 				{
3792 					rowcnt = startNextRow;
3793 					startNextRow = -1;
3794 				}
3795 				else
3796 				{
3797 					rowcnt = 0;
3798 				}
3799 
3800 				if (patternIndexToPlay == -1)
3801 				{
3802 					// play next order
3803 					setNewPosition(poscnt+1);
3804 				}
3805 				// We have one pattern to play but repeating isn't allowed, so stop here
3806 				else if (!repeat)
3807 				{
3808 					halt();
3809 					return;
3810 				}
3811 				// We have one pattern to play and repeating is allowed so start again
3812 				else
3813 				{
3814 					rowcnt = 0;
3815 					// reset looping flags
3816 					RESET_ALL_LOOPING
3817 				}
3818 
3819 			}
3820 
3821 			// halting has been requested
3822 			if (haltFlag)
3823 			{
3824 				halt();
3825 			}
3826 
3827 		}
3828 
3829 	}
3830 	else
3831 	{
3832 		numChannels = module->header.channum;
3833 	}
3834 
3835 	update();
3836 
3837 }
3838 
halt()3839 void PlayerIT::halt()
3840 {
3841 	halted = true;
3842 	BPMCounter = adder = 0;
3843 	if (resetOnStopFlag)
3844 		resetChannelsWithoutMuting();
3845 }
3846 
grabChannelInfo(mp_sint32 chn,TPlayerChannelInfo & channelInfo) const3847 bool PlayerIT::grabChannelInfo(mp_sint32 chn, TPlayerChannelInfo& channelInfo) const
3848 {
3849 	channelInfo.note = chninfo[chn].currentnote;
3850 	channelInfo.instrument = chninfo[chn].getIns();
3851 	channelInfo.volume = chninfo[chn].getVol();
3852 	channelInfo.panning = chninfo[chn].getPan();
3853 	channelInfo.numeffects = numEffects;
3854 	memcpy(channelInfo.effects, chninfo[chn].eff, sizeof(chninfo[chn].eff));
3855 	memcpy(channelInfo.operands, chninfo[chn].eop, sizeof(chninfo[chn].eop));
3856 	return true;
3857 }
3858