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