mplayer.c
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:77k
源码类别:

Windows CE

开发平台:

C/C++

  1. /* MikMod sound library
  2. (c) 1998, 1999, 2000, 2001 Miodrag Vallat and others - see file AUTHORS
  3. for complete list.
  4. This library is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU Library General Public License as
  6. published by the Free Software Foundation; either version 2 of
  7. the License, or (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. GNU Library General Public License for more details.
  13.  
  14. You should have received a copy of the GNU Library General Public
  15. License along with this library; if not, write to the Free Software
  16. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  17. 02111-1307, USA.
  18. */
  19. /*==============================================================================
  20.   $Id: mplayer.c,v 1.5 2004/01/31 22:40:22 raph Exp $
  21.   The Protracker Player Driver
  22.   The protracker driver supports all base Protracker 3.x commands and features.
  23. ==============================================================================*/
  24. #ifdef HAVE_CONFIG_H
  25. #include "config.h"
  26. #endif
  27. #include <string.h>
  28. #include <stdarg.h>
  29. #ifdef SRANDOM_IN_MATH_H
  30. #include <math.h>
  31. #else
  32. #include <stdlib.h>
  33. #endif
  34. #include "mikmod_internals.h"
  35. #ifdef SUNOS
  36. extern int fprintf(FILE *, const char *, ...);
  37. extern long int random(void);
  38. #endif
  39. /* The currently playing module */
  40. /* This variable should better be static, but it would break the ABI, so this
  41.    will wait */
  42. /*static*/ MODULE *pf = NULL;
  43. #define HIGH_OCTAVE 2 /* number of above-range octaves */
  44. static UWORD oldperiods[OCTAVE*2]={
  45. 0x6b00, 0x6800, 0x6500, 0x6220, 0x5f50, 0x5c80,
  46. 0x5a00, 0x5740, 0x54d0, 0x5260, 0x5010, 0x4dc0,
  47. 0x4b90, 0x4960, 0x4750, 0x4540, 0x4350, 0x4160,
  48. 0x3f90, 0x3dc0, 0x3c10, 0x3a40, 0x38b0, 0x3700
  49. };
  50. static UBYTE VibratoTable[32]={
  51.   0, 24, 49, 74, 97,120,141,161,180,197,212,224,235,244,250,253,
  52. 255,253,250,244,235,224,212,197,180,161,141,120, 97, 74, 49, 24
  53. };
  54. static UBYTE avibtab[128]={
  55.  0, 1, 3, 4, 6, 7, 9,10,12,14,15,17,18,20,21,23,
  56. 24,25,27,28,30,31,32,34,35,36,38,39,40,41,42,44,
  57. 45,46,47,48,49,50,51,52,53,54,54,55,56,57,57,58,
  58. 59,59,60,60,61,61,62,62,62,63,63,63,63,63,63,63,
  59. 64,63,63,63,63,63,63,63,62,62,62,61,61,60,60,59,
  60. 59,58,57,57,56,55,54,54,53,52,51,50,49,48,47,46,
  61. 45,44,42,41,40,39,38,36,35,34,32,31,30,28,27,25,
  62. 24,23,21,20,18,17,15,14,12,10, 9, 7, 6, 4, 3, 1
  63. };
  64. /* Triton's linear periods to frequency translation table (for XM modules) */
  65. static ULONG lintab[768]={
  66. 535232,534749,534266,533784,533303,532822,532341,531861,
  67. 531381,530902,530423,529944,529466,528988,528511,528034,
  68. 527558,527082,526607,526131,525657,525183,524709,524236,
  69. 523763,523290,522818,522346,521875,521404,520934,520464,
  70. 519994,519525,519057,518588,518121,517653,517186,516720,
  71. 516253,515788,515322,514858,514393,513929,513465,513002,
  72. 512539,512077,511615,511154,510692,510232,509771,509312,
  73. 508852,508393,507934,507476,507018,506561,506104,505647,
  74. 505191,504735,504280,503825,503371,502917,502463,502010,
  75. 501557,501104,500652,500201,499749,499298,498848,498398,
  76. 497948,497499,497050,496602,496154,495706,495259,494812,
  77. 494366,493920,493474,493029,492585,492140,491696,491253,
  78. 490809,490367,489924,489482,489041,488600,488159,487718,
  79. 487278,486839,486400,485961,485522,485084,484647,484210,
  80. 483773,483336,482900,482465,482029,481595,481160,480726,
  81. 480292,479859,479426,478994,478562,478130,477699,477268,
  82. 476837,476407,475977,475548,475119,474690,474262,473834,
  83. 473407,472979,472553,472126,471701,471275,470850,470425,
  84. 470001,469577,469153,468730,468307,467884,467462,467041,
  85. 466619,466198,465778,465358,464938,464518,464099,463681,
  86. 463262,462844,462427,462010,461593,461177,460760,460345,
  87. 459930,459515,459100,458686,458272,457859,457446,457033,
  88. 456621,456209,455797,455386,454975,454565,454155,453745,
  89. 453336,452927,452518,452110,451702,451294,450887,450481,
  90. 450074,449668,449262,448857,448452,448048,447644,447240,
  91. 446836,446433,446030,445628,445226,444824,444423,444022,
  92. 443622,443221,442821,442422,442023,441624,441226,440828,
  93. 440430,440033,439636,439239,438843,438447,438051,437656,
  94. 437261,436867,436473,436079,435686,435293,434900,434508,
  95. 434116,433724,433333,432942,432551,432161,431771,431382,
  96. 430992,430604,430215,429827,429439,429052,428665,428278,
  97. 427892,427506,427120,426735,426350,425965,425581,425197,
  98. 424813,424430,424047,423665,423283,422901,422519,422138,
  99. 421757,421377,420997,420617,420237,419858,419479,419101,
  100. 418723,418345,417968,417591,417214,416838,416462,416086,
  101. 415711,415336,414961,414586,414212,413839,413465,413092,
  102. 412720,412347,411975,411604,411232,410862,410491,410121,
  103. 409751,409381,409012,408643,408274,407906,407538,407170,
  104. 406803,406436,406069,405703,405337,404971,404606,404241,
  105. 403876,403512,403148,402784,402421,402058,401695,401333,
  106. 400970,400609,400247,399886,399525,399165,398805,398445,
  107. 398086,397727,397368,397009,396651,396293,395936,395579,
  108. 395222,394865,394509,394153,393798,393442,393087,392733,
  109. 392378,392024,391671,391317,390964,390612,390259,389907,
  110. 389556,389204,388853,388502,388152,387802,387452,387102,
  111. 386753,386404,386056,385707,385359,385012,384664,384317,
  112. 383971,383624,383278,382932,382587,382242,381897,381552,
  113. 381208,380864,380521,380177,379834,379492,379149,378807,
  114. 378466,378124,377783,377442,377102,376762,376422,376082,
  115. 375743,375404,375065,374727,374389,374051,373714,373377,
  116. 373040,372703,372367,372031,371695,371360,371025,370690,
  117. 370356,370022,369688,369355,369021,368688,368356,368023,
  118. 367691,367360,367028,366697,366366,366036,365706,365376,
  119. 365046,364717,364388,364059,363731,363403,363075,362747,
  120. 362420,362093,361766,361440,361114,360788,360463,360137,
  121. 359813,359488,359164,358840,358516,358193,357869,357547,
  122. 357224,356902,356580,356258,355937,355616,355295,354974,
  123. 354654,354334,354014,353695,353376,353057,352739,352420,
  124. 352103,351785,351468,351150,350834,350517,350201,349885,
  125. 349569,349254,348939,348624,348310,347995,347682,347368,
  126. 347055,346741,346429,346116,345804,345492,345180,344869,
  127. 344558,344247,343936,343626,343316,343006,342697,342388,
  128. 342079,341770,341462,341154,340846,340539,340231,339924,
  129. 339618,339311,339005,338700,338394,338089,337784,337479,
  130. 337175,336870,336566,336263,335959,335656,335354,335051,
  131. 334749,334447,334145,333844,333542,333242,332941,332641,
  132. 332341,332041,331741,331442,331143,330844,330546,330247,
  133. 329950,329652,329355,329057,328761,328464,328168,327872,
  134. 327576,327280,326985,326690,326395,326101,325807,325513,
  135. 325219,324926,324633,324340,324047,323755,323463,323171,
  136. 322879,322588,322297,322006,321716,321426,321136,320846,
  137. 320557,320267,319978,319690,319401,319113,318825,318538,
  138. 318250,317963,317676,317390,317103,316817,316532,316246,
  139. 315961,315676,315391,315106,314822,314538,314254,313971,
  140. 313688,313405,313122,312839,312557,312275,311994,311712,
  141. 311431,311150,310869,310589,310309,310029,309749,309470,
  142. 309190,308911,308633,308354,308076,307798,307521,307243,
  143. 306966,306689,306412,306136,305860,305584,305308,305033,
  144. 304758,304483,304208,303934,303659,303385,303112,302838,
  145. 302565,302292,302019,301747,301475,301203,300931,300660,
  146. 300388,300117,299847,299576,299306,299036,298766,298497,
  147. 298227,297958,297689,297421,297153,296884,296617,296349,
  148. 296082,295815,295548,295281,295015,294749,294483,294217,
  149. 293952,293686,293421,293157,292892,292628,292364,292100,
  150. 291837,291574,291311,291048,290785,290523,290261,289999,
  151. 289737,289476,289215,288954,288693,288433,288173,287913,
  152. 287653,287393,287134,286875,286616,286358,286099,285841,
  153. 285583,285326,285068,284811,284554,284298,284041,283785,
  154. 283529,283273,283017,282762,282507,282252,281998,281743,
  155. 281489,281235,280981,280728,280475,280222,279969,279716,
  156. 279464,279212,278960,278708,278457,278206,277955,277704,
  157. 277453,277203,276953,276703,276453,276204,275955,275706,
  158. 275457,275209,274960,274712,274465,274217,273970,273722,
  159. 273476,273229,272982,272736,272490,272244,271999,271753,
  160. 271508,271263,271018,270774,270530,270286,270042,269798,
  161. 269555,269312,269069,268826,268583,268341,268099,267857
  162. };
  163. #define LOGFAC 2*16
  164. static UWORD logtab[104]={
  165. LOGFAC*907,LOGFAC*900,LOGFAC*894,LOGFAC*887,
  166. LOGFAC*881,LOGFAC*875,LOGFAC*868,LOGFAC*862,
  167. LOGFAC*856,LOGFAC*850,LOGFAC*844,LOGFAC*838,
  168. LOGFAC*832,LOGFAC*826,LOGFAC*820,LOGFAC*814,
  169. LOGFAC*808,LOGFAC*802,LOGFAC*796,LOGFAC*791,
  170. LOGFAC*785,LOGFAC*779,LOGFAC*774,LOGFAC*768,
  171. LOGFAC*762,LOGFAC*757,LOGFAC*752,LOGFAC*746,
  172. LOGFAC*741,LOGFAC*736,LOGFAC*730,LOGFAC*725,
  173. LOGFAC*720,LOGFAC*715,LOGFAC*709,LOGFAC*704,
  174. LOGFAC*699,LOGFAC*694,LOGFAC*689,LOGFAC*684,
  175. LOGFAC*678,LOGFAC*675,LOGFAC*670,LOGFAC*665,
  176. LOGFAC*660,LOGFAC*655,LOGFAC*651,LOGFAC*646,
  177. LOGFAC*640,LOGFAC*636,LOGFAC*632,LOGFAC*628,
  178. LOGFAC*623,LOGFAC*619,LOGFAC*614,LOGFAC*610,
  179. LOGFAC*604,LOGFAC*601,LOGFAC*597,LOGFAC*592,
  180. LOGFAC*588,LOGFAC*584,LOGFAC*580,LOGFAC*575,
  181. LOGFAC*570,LOGFAC*567,LOGFAC*563,LOGFAC*559,
  182. LOGFAC*555,LOGFAC*551,LOGFAC*547,LOGFAC*543,
  183. LOGFAC*538,LOGFAC*535,LOGFAC*532,LOGFAC*528,
  184. LOGFAC*524,LOGFAC*520,LOGFAC*516,LOGFAC*513,
  185. LOGFAC*508,LOGFAC*505,LOGFAC*502,LOGFAC*498,
  186. LOGFAC*494,LOGFAC*491,LOGFAC*487,LOGFAC*484,
  187. LOGFAC*480,LOGFAC*477,LOGFAC*474,LOGFAC*470,
  188. LOGFAC*467,LOGFAC*463,LOGFAC*460,LOGFAC*457,
  189. LOGFAC*453,LOGFAC*450,LOGFAC*447,LOGFAC*443,
  190. LOGFAC*440,LOGFAC*437,LOGFAC*434,LOGFAC*431
  191. };
  192. static SBYTE PanbrelloTable[256]={
  193.   0,  2,  3,  5,  6,  8,  9, 11, 12, 14, 16, 17, 19, 20, 22, 23,
  194.  24, 26, 27, 29, 30, 32, 33, 34, 36, 37, 38, 39, 41, 42, 43, 44,
  195.  45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 56, 57, 58, 59,
  196.  59, 60, 60, 61, 61, 62, 62, 62, 63, 63, 63, 64, 64, 64, 64, 64,
  197.  64, 64, 64, 64, 64, 64, 63, 63, 63, 62, 62, 62, 61, 61, 60, 60,
  198.  59, 59, 58, 57, 56, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46,
  199.  45, 44, 43, 42, 41, 39, 38, 37, 36, 34, 33, 32, 30, 29, 27, 26,
  200.  24, 23, 22, 20, 19, 17, 16, 14, 12, 11,  9,  8,  6,  5,  3,  2,
  201.   0,- 2,- 3,- 5,- 6,- 8,- 9,-11,-12,-14,-16,-17,-19,-20,-22,-23,
  202. -24,-26,-27,-29,-30,-32,-33,-34,-36,-37,-38,-39,-41,-42,-43,-44,
  203. -45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-56,-57,-58,-59,
  204. -59,-60,-60,-61,-61,-62,-62,-62,-63,-63,-63,-64,-64,-64,-64,-64,
  205. -64,-64,-64,-64,-64,-64,-63,-63,-63,-62,-62,-62,-61,-61,-60,-60,
  206. -59,-59,-58,-57,-56,-56,-55,-54,-53,-52,-51,-50,-49,-48,-47,-46,
  207. -45,-44,-43,-42,-41,-39,-38,-37,-36,-34,-33,-32,-30,-29,-27,-26,
  208. -24,-23,-22,-20,-19,-17,-16,-14,-12,-11,- 9,- 8,- 6,- 5,- 3,- 2
  209. };
  210. /* returns a random value between 0 and ceil-1, ceil must be a power of two */
  211. static int getrandom(int ceil)
  212. {
  213. #ifdef HAVE_SRANDOM
  214. return random()&(ceil-1);
  215. #else
  216. return (rand()*ceil)/(RAND_MAX+1.0);
  217. #endif
  218. }
  219. /* New Note Action Scoring System :
  220. --------------------------------
  221. 1) total-volume (fadevol, chanvol, volume) is the main scorer.
  222. 2) a looping sample is a bonus x2
  223. 3) a foreground channel is a bonus x4
  224. 4) an active envelope with keyoff is a handicap -x2
  225. */
  226. static int MP_FindEmptyChannel(MODULE *mod)
  227. {
  228. MP_VOICE *a;
  229. ULONG t,k,tvol,pp;
  230. for (t=0;t<md_sngchn;t++)
  231. if (((mod->voice[t].main.kick==KICK_ABSENT)||
  232.  (mod->voice[t].main.kick==KICK_ENV))&&
  233.    Voice_Stopped_internal(t))
  234. return t;
  235. tvol=0xffffffUL;t=-1;a=mod->voice;
  236. for (k=0;k<md_sngchn;k++,a++) {
  237. /* allow us to take over a nonexisting sample */
  238. if (!a->main.s)
  239. return k;
  240. if ((a->main.kick==KICK_ABSENT)||(a->main.kick==KICK_ENV)) {
  241. pp=a->totalvol<<((a->main.s->flags&SF_LOOP)?1:0);
  242. if ((a->master)&&(a==a->master->slave))
  243. pp<<=2;
  244. if (pp<tvol) {
  245. tvol=pp;
  246. t=k;
  247. }
  248. }
  249. }
  250. if (tvol>8000*7) return -1;
  251. return t;
  252. }
  253. static SWORD Interpolate(SWORD p,SWORD p1,SWORD p2,SWORD v1,SWORD v2)
  254. {
  255. if ((p1==p2)||(p==p1)) return v1;
  256. return v1+((SLONG)((p-p1)*(v2-v1))/(p2-p1));
  257. }
  258. UWORD getlinearperiod(UWORD note,ULONG fine)
  259. {
  260. UWORD t;
  261. t=((20L+2*HIGH_OCTAVE)*OCTAVE+2-note)*32L-(fine>>1);
  262. return t;
  263. }
  264. static UWORD getlogperiod(UWORD note,ULONG fine)
  265. {
  266. UWORD n,o;
  267. UWORD p1,p2;
  268. ULONG i;
  269. n=note%(2*OCTAVE);
  270. o=note/(2*OCTAVE);
  271. i=(n<<2)+(fine>>4); /* n*8 + fine/16 */
  272. p1=logtab[i];
  273. p2=logtab[i+1];
  274. return (Interpolate(fine>>4,0,15,p1,p2)>>o);
  275. }
  276. static UWORD getoldperiod(UWORD note,ULONG speed)
  277. {
  278. UWORD n,o;
  279. /* This happens sometimes on badly converted AMF, and old MOD */
  280. if (!speed) {
  281. #ifdef MIKMOD_DEBUG
  282. fprintf(stderr,"rmplayer: getoldperiod() called with note=%d, speed=0 !n",note);
  283. #endif
  284. return 4242; /* <- prevent divide overflow.. (42 hehe) */
  285. }
  286. n=note%(2*OCTAVE);
  287. o=note/(2*OCTAVE);
  288. return ((8363L*(ULONG)oldperiods[n])>>o)/speed;
  289. }
  290. static UWORD GetPeriod(UWORD flags, UWORD note, ULONG speed)
  291. {
  292. if (flags & UF_XMPERIODS) {
  293. if (flags & UF_LINEAR)
  294. return getlinearperiod(note, speed);
  295. else
  296. return getlogperiod(note, speed);
  297. } else
  298. return getoldperiod(note, speed);
  299. }
  300. static SWORD InterpolateEnv(SWORD p,ENVPT *a,ENVPT *b)
  301. {
  302. return (Interpolate(p,a->pos,b->pos,a->val,b->val));
  303. }
  304. static SWORD DoPan(SWORD envpan,SWORD pan)
  305. {
  306. int newpan;
  307. newpan=pan+(((envpan-PAN_CENTER)*(128-abs(pan-PAN_CENTER)))/128);
  308. return (newpan<PAN_LEFT)?PAN_LEFT:(newpan>PAN_RIGHT?PAN_RIGHT:newpan);
  309. }
  310. static SWORD StartEnvelope(ENVPR *t,UBYTE flg,UBYTE pts,UBYTE susbeg,UBYTE susend,UBYTE beg,UBYTE end,ENVPT *p,UBYTE keyoff)
  311. {
  312. t->flg=flg;
  313. t->pts=pts;
  314. t->susbeg=susbeg;
  315. t->susend=susend;
  316. t->beg=beg;
  317. t->end=end;
  318. t->env=p;
  319. t->p=0;
  320. t->a=0;
  321. t->b=((t->flg&EF_SUSTAIN)&&(!(keyoff&KEY_OFF)))?0:1;
  322. /* Imago Orpheus sometimes stores an extra initial point in the envelope */
  323. if ((t->pts>=2)&&(t->env[0].pos==t->env[1].pos)) {
  324. t->a++;t->b++;
  325. }
  326. /* Fit in the envelope, still */
  327. if (t->a >= t->pts)
  328. t->a = t->pts - 1;
  329. if (t->b >= t->pts)
  330. t->b = t->pts-1;
  331. return t->env[t->a].val;
  332. }
  333. /* This procedure processes all envelope types, include volume, pitch, and
  334.    panning.  Envelopes are defined by a set of points, each with a magnitude
  335.    [relating either to volume, panning position, or pitch modifier] and a tick
  336.    position.
  337.    Envelopes work in the following manner:
  338.    (a) Each tick the envelope is moved a point further in its progression. For
  339.        an accurate progression, magnitudes between two envelope points are
  340.        interpolated.
  341.    (b) When progression reaches a defined point on the envelope, values are
  342.        shifted to interpolate between this point and the next, and checks for
  343.        loops or envelope end are done.
  344.    Misc:
  345.      Sustain loops are loops that are only active as long as the keyoff flag is
  346.      clear.  When a volume envelope terminates, so does the current fadeout.
  347. */
  348. static SWORD ProcessEnvelope(MP_VOICE *aout, ENVPR *t, SWORD v)
  349. {
  350. if (t->flg & EF_ON) {
  351. UBYTE a, b; /* actual points in the envelope */
  352. UWORD p; /* the 'tick counter' - real point being played */
  353. a = t->a;
  354. b = t->b;
  355. p = t->p;
  356. /*
  357.  * Sustain loop on one point (XM type).
  358.  * Not processed if KEYOFF.
  359.  * Don't move and don't interpolate when the point is reached
  360.  */
  361. if ((t->flg & EF_SUSTAIN) && t->susbeg == t->susend &&
  362.    (!(aout->main.keyoff & KEY_OFF) && p == t->env[t->susbeg].pos)) {
  363. v = t->env[t->susbeg].val;
  364. } else {
  365. /*
  366.  * All following situations will require interpolation between
  367.  * two envelope points.
  368.  */
  369. /*
  370.  * Sustain loop between two points (IT type).
  371.  * Not processed if KEYOFF.
  372.  */
  373. /* if we were on a loop point, loop now */
  374. if ((t->flg & EF_SUSTAIN) && !(aout->main.keyoff & KEY_OFF) &&
  375.    a >= t->susend) {
  376. a = t->susbeg;
  377. b = (t->susbeg==t->susend)?a:a+1;
  378. p = t->env[a].pos;
  379. v = t->env[a].val;
  380. } else
  381. /*
  382.  * Regular loop.
  383.  * Be sure to correctly handle single point loops.
  384.  */
  385. if ((t->flg & EF_LOOP) && a >= t->end) {
  386. a = t->beg;
  387. b = t->beg == t->end ? a : a + 1;
  388. p = t->env[a].pos;
  389. v = t->env[a].val;
  390. } else
  391. /*
  392.  * Non looping situations.
  393.  */
  394. if (a != b)
  395. v = InterpolateEnv(p, &t->env[a], &t->env[b]);
  396. else
  397. v = t->env[a].val;
  398. /*
  399.  * Start to fade if the volume envelope is finished.
  400.  */
  401. if (p >= t->env[t->pts - 1].pos) {
  402. if (t->flg & EF_VOLENV) {
  403. aout->main.keyoff |= KEY_FADE;
  404. if (!v)
  405. aout->main.fadevol = 0;
  406. }
  407. } else {
  408. p++;
  409. /* did pointer reach point b? */
  410. if (p >= t->env[b].pos)
  411. a = b++; /* shift points a and b */
  412. }
  413. t->a = a;
  414. t->b = b;
  415. t->p = p;
  416. }
  417. }
  418. return v;
  419. }
  420. /* XM linear period to frequency conversion */
  421. ULONG getfrequency(UWORD flags,ULONG period)
  422. {
  423. if (flags & UF_LINEAR) {
  424. SLONG shift = ((SLONG)period / 768) - HIGH_OCTAVE;
  425. if (shift >= 0)
  426. return lintab[period % 768] >> shift;
  427. else
  428. return lintab[period % 768] << (-shift);
  429. } else
  430. return (8363L*1712L)/(period?period:1);
  431. }
  432. /*========== Protracker effects */
  433. static void DoArpeggio(UWORD tick, UWORD flags, MP_CONTROL *a, UBYTE style)
  434. {
  435. UBYTE note=a->main.note;
  436. if (a->arpmem) {
  437. switch (style) {
  438. case 0: /* mod style: N, N+x, N+y */
  439. switch (tick % 3) {
  440. /* case 0: unchanged */
  441. case 1:
  442. note += (a->arpmem >> 4);
  443. break;
  444. case 2:
  445. note += (a->arpmem & 0xf);
  446. break;
  447. }
  448. break;
  449. case 3: /* okt arpeggio 3: N-x, N, N+y */
  450. switch (tick % 3) {
  451. case 0:
  452. note -= (a->arpmem >> 4);
  453. break;
  454. /* case 1: unchanged */
  455. case 2:
  456. note += (a->arpmem & 0xf);
  457. break;
  458. }
  459. break;
  460. case 4: /* okt arpeggio 4: N, N+y, N, N-x */
  461. switch (tick % 4) {
  462. /* case 0, case 2: unchanged */
  463. case 1:
  464. note += (a->arpmem & 0xf);
  465. break;
  466. case 3:
  467. note -= (a->arpmem >> 4);
  468. break;
  469. }
  470. break;
  471. case 5: /* okt arpeggio 5: N-x, N+y, N, and nothing at tick 0 */
  472. if (!tick)
  473. break;
  474. switch (tick % 3) {
  475. /* case 0: unchanged */
  476. case 1:
  477. note -= (a->arpmem >> 4);
  478. break;
  479. case 2:
  480. note += (a->arpmem & 0xf);
  481. break;
  482. }
  483. break;
  484. }
  485. a->main.period = GetPeriod(flags, (UWORD)note << 1, a->speed);
  486. a->ownper = 1;
  487. }
  488. }
  489. static int DoPTEffect0(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
  490. {
  491. UBYTE dat;
  492. dat = UniGetByte();
  493. if (!tick) {
  494. if (!dat && (flags & UF_ARPMEM))
  495. dat=a->arpmem;
  496. else
  497. a->arpmem=dat;
  498. }
  499. if (a->main.period)
  500. DoArpeggio(tick, flags, a, 0);
  501. return 0;
  502. }
  503. static int DoPTEffect1(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
  504. {
  505. UBYTE dat;
  506. dat = UniGetByte();
  507. if (!tick && dat)
  508. a->slidespeed = (UWORD)dat << 2;
  509. if (a->main.period)
  510. if (tick)
  511. a->tmpperiod -= a->slidespeed;
  512. return 0;
  513. }
  514. static int DoPTEffect2(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
  515. {
  516. UBYTE dat;
  517. dat = UniGetByte();
  518. if (!tick && dat)
  519. a->slidespeed = (UWORD)dat << 2;
  520. if (a->main.period)
  521. if (tick)
  522. a->tmpperiod += a->slidespeed;
  523. return 0;
  524. }
  525. static void DoToneSlide(UWORD tick, MP_CONTROL *a)
  526. {
  527. if (!a->main.fadevol)
  528. a->main.kick = (a->main.kick == KICK_NOTE)? KICK_NOTE : KICK_KEYOFF;
  529. else
  530. a->main.kick = (a->main.kick == KICK_NOTE)? KICK_ENV : KICK_ABSENT;
  531. if (tick != 0) {
  532. int dist;
  533. /* We have to slide a->main.period towards a->wantedperiod, so compute
  534.    the difference between those two values */
  535. dist=a->main.period-a->wantedperiod;
  536. /* if they are equal or if portamentospeed is too big ...*/
  537. if (dist == 0 || a->portspeed > abs(dist))
  538. /* ...make tmpperiod equal tperiod */
  539. a->tmpperiod=a->main.period=a->wantedperiod;
  540. else if (dist>0) {
  541. a->tmpperiod-=a->portspeed;
  542. a->main.period-=a->portspeed; /* dist>0, slide up */
  543. } else {
  544. a->tmpperiod+=a->portspeed;
  545. a->main.period+=a->portspeed; /* dist<0, slide down */
  546. }
  547. } else
  548. a->tmpperiod=a->main.period;
  549. a->ownper = 1;
  550. }
  551. static int DoPTEffect3(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
  552. {
  553. UBYTE dat;
  554. dat=UniGetByte();
  555. if ((!tick)&&(dat)) a->portspeed=(UWORD)dat<<2;
  556. if (a->main.period)
  557. DoToneSlide(tick, a);
  558. return 0;
  559. }
  560. static void DoVibrato(UWORD tick, MP_CONTROL *a)
  561. {
  562. UBYTE q;
  563. UWORD temp = 0; /* silence warning */
  564. if (!tick)
  565. return;
  566. q=(a->vibpos>>2)&0x1f;
  567. switch (a->wavecontrol&3) {
  568. case 0: /* sine */
  569. temp=VibratoTable[q];
  570. break;
  571. case 1: /* ramp down */
  572. q<<=3;
  573. if (a->vibpos<0) q=255-q;
  574. temp=q;
  575. break;
  576. case 2: /* square wave */
  577. temp=255;
  578. break;
  579. case 3: /* random wave */
  580. temp=getrandom(256);
  581. break;
  582. }
  583. temp*=a->vibdepth;
  584. temp>>=7;temp<<=2;
  585. if (a->vibpos>=0)
  586. a->main.period=a->tmpperiod+temp;
  587. else
  588. a->main.period=a->tmpperiod-temp;
  589. a->ownper = 1;
  590. if (tick != 0)
  591. a->vibpos+=a->vibspd;
  592. }
  593. static int DoPTEffect4(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
  594. {
  595. UBYTE dat;
  596. dat=UniGetByte();
  597. if (!tick) {
  598. if (dat&0x0f) a->vibdepth=dat&0xf;
  599. if (dat&0xf0) a->vibspd=(dat&0xf0)>>2;
  600. }
  601. if (a->main.period)
  602. DoVibrato(tick, a);
  603. return 0;
  604. }
  605. static void DoVolSlide(MP_CONTROL *a, UBYTE dat)
  606. {
  607. if (dat&0xf) {
  608. a->tmpvolume-=(dat&0x0f);
  609. if (a->tmpvolume<0)
  610. a->tmpvolume=0;
  611. } else {
  612. a->tmpvolume+=(dat>>4);
  613. if (a->tmpvolume>64)
  614. a->tmpvolume=64;
  615. }
  616. }
  617. static int DoPTEffect5(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
  618. {
  619. UBYTE dat;
  620. dat=UniGetByte();
  621. if (a->main.period)
  622. DoToneSlide(tick, a);
  623. if (tick)
  624. DoVolSlide(a, dat);
  625. return 0;
  626. }
  627. /* DoPTEffect6 after DoPTEffectA */
  628. static int DoPTEffect7(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
  629. {
  630. UBYTE dat;
  631. UBYTE q;
  632. UWORD temp = 0; /* silence warning */
  633. dat=UniGetByte();
  634. if (!tick) {
  635. if (dat&0x0f) a->trmdepth=dat&0xf;
  636. if (dat&0xf0) a->trmspd=(dat&0xf0)>>2;
  637. }
  638. if (a->main.period) {
  639. q=(a->trmpos>>2)&0x1f;
  640. switch ((a->wavecontrol>>4)&3) {
  641. case 0: /* sine */
  642. temp=VibratoTable[q];
  643. break;
  644. case 1: /* ramp down */
  645. q<<=3;
  646. if (a->trmpos<0) q=255-q;
  647. temp=q;
  648. break;
  649. case 2: /* square wave */
  650. temp=255;
  651. break;
  652. case 3: /* random wave */
  653. temp=getrandom(256);
  654. break;
  655. }
  656. temp*=a->trmdepth;
  657. temp>>=6;
  658. if (a->trmpos>=0) {
  659. a->volume=a->tmpvolume+temp;
  660. if (a->volume>64) a->volume=64;
  661. } else {
  662. a->volume=a->tmpvolume-temp;
  663. if (a->volume<0) a->volume=0;
  664. }
  665. a->ownvol = 1;
  666. if (tick)
  667. a->trmpos+=a->trmspd;
  668. }
  669. return 0;
  670. }
  671. static int DoPTEffect8(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
  672. {
  673. UBYTE dat;
  674. dat = UniGetByte();
  675. if (mod->panflag)
  676. a->main.panning = mod->panning[channel] = dat;
  677. return 0;
  678. }
  679. static int DoPTEffect9(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
  680. {
  681. UBYTE dat;
  682. dat=UniGetByte();
  683. if (!tick) {
  684. if (dat) a->soffset=(UWORD)dat<<8;
  685. a->main.start=a->hioffset|a->soffset;
  686. if ((a->main.s)&&(a->main.start>a->main.s->length))
  687. a->main.start=a->main.s->flags&(SF_LOOP|SF_BIDI)?
  688.     a->main.s->loopstart:a->main.s->length;
  689. }
  690. return 0;
  691. }
  692. static int DoPTEffectA(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
  693. {
  694. UBYTE dat;
  695. dat=UniGetByte();
  696. if (tick)
  697. DoVolSlide(a, dat);
  698. return 0;
  699. }
  700. static int DoPTEffect6(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
  701. {
  702. if (a->main.period)
  703. DoVibrato(tick, a);
  704. DoPTEffectA(tick, flags, a, mod, channel);
  705. return 0;
  706. }
  707. static int DoPTEffectB(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
  708. {
  709. UBYTE dat;
  710. dat=UniGetByte();
  711. if (tick || mod->patdly2)
  712. return 0;
  713. /* Vincent Voois uses a nasty trick in "Universal Bolero" */
  714. if (dat == mod->sngpos && mod->patbrk == mod->patpos)
  715. return 0;
  716. if (!mod->loop && !mod->patbrk &&
  717.     (dat < mod->sngpos ||
  718.  (mod->sngpos == (mod->numpos - 1) && !mod->patbrk) ||
  719.      (dat == mod->sngpos && (flags & UF_NOWRAP))
  720. )) {
  721. /* if we don't loop, better not to skip the end of the
  722.    pattern, after all... so:
  723. mod->patbrk=0; */
  724. mod->posjmp=3;
  725. } else {
  726. /* if we were fading, adjust... */
  727. if (mod->sngpos == (mod->numpos-1))
  728. mod->volume=mod->initvolume>128?128:mod->initvolume;
  729. mod->sngpos=dat;
  730. mod->posjmp=2;
  731. mod->patpos=0;
  732. }
  733. return 0;
  734. }
  735. static int DoPTEffectC(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
  736. {
  737. UBYTE dat;
  738. dat=UniGetByte();
  739. if (tick) return 0;
  740. if (dat==(UBYTE)-1) a->anote=dat=0; /* note cut */
  741. else if (dat>64) dat=64;
  742. a->tmpvolume=dat;
  743. return 0;
  744. }
  745. static int DoPTEffectD(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
  746. {
  747. UBYTE dat;
  748. dat=UniGetByte();
  749. if ((tick)||(mod->patdly2)) return 0;
  750. if ((mod->positions[mod->sngpos]!=LAST_PATTERN)&&
  751.    (dat>mod->pattrows[mod->positions[mod->sngpos]]))
  752. dat=mod->pattrows[mod->positions[mod->sngpos]];
  753. mod->patbrk=dat;
  754. if (!mod->posjmp) {
  755. /* don't ask me to explain this code - it makes
  756.    backwards.s3m and children.xm (heretic's version) play
  757.    correctly, among others. Take that for granted, or write
  758.    the page of comments yourself... you might need some
  759.    aspirin - Miod */
  760. if ((mod->sngpos==mod->numpos-1)&&(dat)&&((mod->loop)||
  761.                (mod->positions[mod->sngpos]==(mod->numpat-1)
  762. && !(flags&UF_NOWRAP)))) {
  763. mod->sngpos=0;
  764. mod->posjmp=2;
  765. } else
  766. mod->posjmp=3;
  767. }
  768. return 0;
  769. }
  770. static void DoEEffects(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod,
  771. SWORD channel, UBYTE dat)
  772. {
  773. UBYTE nib = dat & 0xf;
  774. switch (dat>>4) {
  775. case 0x0: /* hardware filter toggle, not supported */
  776. break;
  777. case 0x1: /* fineslide up */
  778. if (a->main.period)
  779. if (!tick)
  780. a->tmpperiod-=(nib<<2);
  781. break;
  782. case 0x2: /* fineslide dn */
  783. if (a->main.period)
  784. if (!tick)
  785. a->tmpperiod+=(nib<<2);
  786. break;
  787. case 0x3: /* glissando ctrl */
  788. a->glissando=nib;
  789. break;
  790. case 0x4: /* set vibrato waveform */
  791. a->wavecontrol&=0xf0;
  792. a->wavecontrol|=nib;
  793. break;
  794. case 0x5: /* set finetune */
  795. if (a->main.period) {
  796. if (flags&UF_XMPERIODS)
  797. a->speed=nib+128;
  798. else
  799. a->speed=finetune[nib];
  800. a->tmpperiod=GetPeriod(flags, (UWORD)a->main.note<<1,a->speed);
  801. }
  802. break;
  803. case 0x6: /* set patternloop */
  804. if (tick)
  805. break;
  806. if (nib) { /* set reppos or repcnt ? */
  807. /* set repcnt, so check if repcnt already is set, which means we
  808.    are already looping */
  809. if (a->pat_repcnt)
  810. a->pat_repcnt--; /* already looping, decrease counter */
  811. else {
  812. #if 0
  813. /* this would make walker.xm, shipped with Xsoundtracker,
  814.    play correctly, but it's better to remain compatible
  815.    with FT2 */
  816. if ((!(flags&UF_NOWRAP))||(a->pat_reppos!=POS_NONE))
  817. #endif
  818. a->pat_repcnt=nib; /* not yet looping, so set repcnt */
  819. }
  820. if (a->pat_repcnt) { /* jump to reppos if repcnt>0 */
  821. if (a->pat_reppos==POS_NONE)
  822. a->pat_reppos=mod->patpos-1;
  823. if (a->pat_reppos==-1) {
  824. mod->pat_repcrazy=1;
  825. mod->patpos=0;
  826. } else
  827. mod->patpos=a->pat_reppos;
  828. } else a->pat_reppos=POS_NONE;
  829. } else
  830. a->pat_reppos=mod->patpos-1; /* set reppos - can be (-1) */
  831. break;
  832. case 0x7: /* set tremolo waveform */
  833. a->wavecontrol&=0x0f;
  834. a->wavecontrol|=nib<<4;
  835. break;
  836. case 0x8: /* set panning */
  837. if (mod->panflag) {
  838. if (nib<=8) nib<<=4;
  839. else nib*=17;
  840. a->main.panning=mod->panning[channel]=nib;
  841. }
  842. break;
  843. case 0x9: /* retrig note */
  844. /* do not retrigger on tick 0, until we are emulating FT2 and effect
  845.    data is zero */
  846. if (!tick && !((flags & UF_FT2QUIRKS) && (!nib)))
  847. break;
  848. /* only retrigger if data nibble > 0, or if tick 0 (FT2 compat) */
  849. if (nib || !tick) {
  850. if (!a->retrig) {
  851. /* when retrig counter reaches 0, reset counter and restart
  852.    the sample */
  853. if (a->main.period) a->main.kick=KICK_NOTE;
  854. a->retrig=nib;
  855. }
  856. a->retrig--; /* countdown */
  857. }
  858. break;
  859. case 0xa: /* fine volume slide up */
  860. if (tick)
  861. break;
  862. a->tmpvolume+=nib;
  863. if (a->tmpvolume>64) a->tmpvolume=64;
  864. break;
  865. case 0xb: /* fine volume slide dn  */
  866. if (tick)
  867. break;
  868. a->tmpvolume-=nib;
  869. if (a->tmpvolume<0)a->tmpvolume=0;
  870. break;
  871. case 0xc: /* cut note */
  872. /* When tick reaches the cut-note value, turn the volume to
  873.    zero (just like on the amiga) */
  874. if (tick>=nib)
  875. a->tmpvolume=0; /* just turn the volume down */
  876. break;
  877. case 0xd: /* note delay */
  878. /* delay the start of the sample until tick==nib */
  879. if (!tick)
  880. a->main.notedelay=nib;
  881. else if (a->main.notedelay)
  882. a->main.notedelay--;
  883. break;
  884. case 0xe: /* pattern delay */
  885. if (!tick)
  886. if (!mod->patdly2)
  887. mod->patdly=nib+1; /* only once, when tick=0 */
  888. break;
  889. case 0xf: /* invert loop, not supported  */
  890. break;
  891. }
  892. }
  893. static int DoPTEffectE(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
  894. {
  895. DoEEffects(tick, flags, a, mod, channel, UniGetByte());
  896. return 0;
  897. }
  898. static int DoPTEffectF(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
  899. {
  900. UBYTE dat;
  901. dat=UniGetByte();
  902. if (tick||mod->patdly2) return 0;
  903. if (mod->extspd&&(dat>=mod->bpmlimit))
  904. mod->bpm=dat;
  905. else 
  906.   if (dat) {
  907. mod->sngspd=(dat>=mod->bpmlimit)?mod->bpmlimit-1:dat;
  908. mod->vbtick=0;
  909. }
  910. return 0;
  911. }
  912. /*========== Scream Tracker effects */
  913. static int DoS3MEffectA(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
  914. {
  915. UBYTE speed;
  916. speed = UniGetByte();
  917. if (tick || mod->patdly2)
  918. return 0;
  919. if (speed > 128)
  920. speed -= 128;
  921. if (speed) {
  922. mod->sngspd = speed;
  923. mod->vbtick = 0;
  924. }
  925. return 0;
  926. }
  927. static void DoS3MVolSlide(UWORD tick, UWORD flags, MP_CONTROL *a, UBYTE inf)
  928. {
  929. UBYTE lo, hi;
  930. if (inf)
  931. a->s3mvolslide=inf;
  932. else
  933. inf=a->s3mvolslide;
  934. lo=inf&0xf;
  935. hi=inf>>4;
  936. if (!lo) {
  937. if ((tick)||(flags&UF_S3MSLIDES)) a->tmpvolume+=hi;
  938. } else
  939.   if (!hi) {
  940. if ((tick)||(flags&UF_S3MSLIDES)) a->tmpvolume-=lo;
  941. } else
  942.   if (lo==0xf) {
  943. if (!tick) a->tmpvolume+=(hi?hi:0xf);
  944. } else
  945.   if (hi==0xf) {
  946. if (!tick) a->tmpvolume-=(lo?lo:0xf);
  947. } else
  948.   return;
  949. if (a->tmpvolume<0)
  950. a->tmpvolume=0;
  951. else if (a->tmpvolume>64)
  952. a->tmpvolume=64;
  953. }
  954. static int DoS3MEffectD(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
  955. {
  956. DoS3MVolSlide(tick, flags, a, UniGetByte());
  957. return 1;
  958. }
  959. static void DoS3MSlideDn(UWORD tick, MP_CONTROL *a, UBYTE inf)
  960. {
  961. UBYTE hi,lo;
  962. if (inf)
  963. a->slidespeed=inf;
  964. else
  965. inf=a->slidespeed;
  966. hi=inf>>4;
  967. lo=inf&0xf;
  968. if (hi==0xf) {
  969. if (!tick) a->tmpperiod+=(UWORD)lo<<2;
  970. } else
  971.   if (hi==0xe) {
  972. if (!tick) a->tmpperiod+=lo;
  973. } else {
  974. if (tick) a->tmpperiod+=(UWORD)inf<<2;
  975. }
  976. }
  977. static int DoS3MEffectE(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
  978. {
  979. UBYTE dat;
  980. dat=UniGetByte();
  981. if (a->main.period)
  982. DoS3MSlideDn(tick, a,dat);
  983. return 0;
  984. }
  985. static void DoS3MSlideUp(UWORD tick, MP_CONTROL *a, UBYTE inf)
  986. {
  987. UBYTE hi,lo;
  988. if (inf) a->slidespeed=inf;
  989. else inf=a->slidespeed;
  990. hi=inf>>4;
  991. lo=inf&0xf;
  992. if (hi==0xf) {
  993. if (!tick) a->tmpperiod-=(UWORD)lo<<2;
  994. } else
  995.   if (hi==0xe) {
  996. if (!tick) a->tmpperiod-=lo;
  997. } else {
  998. if (tick) a->tmpperiod-=(UWORD)inf<<2;
  999. }
  1000. }
  1001. static int DoS3MEffectF(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
  1002. {
  1003. UBYTE dat;
  1004. dat=UniGetByte();
  1005. if (a->main.period)
  1006. DoS3MSlideUp(tick, a,dat);
  1007. return 0;
  1008. }
  1009. static int DoS3MEffectI(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
  1010. {
  1011. UBYTE inf, on, off;
  1012. inf = UniGetByte();
  1013. if (inf)
  1014. a->s3mtronof = inf;
  1015. else {
  1016. inf = a->s3mtronof;
  1017. if (!inf)
  1018. return 0;
  1019. }
  1020. if (!tick)
  1021. return 0;
  1022. on=(inf>>4)+1;
  1023. off=(inf&0xf)+1;
  1024. a->s3mtremor%=(on+off);
  1025. a->volume=(a->s3mtremor<on)?a->tmpvolume:0;
  1026. a->ownvol=1;
  1027. a->s3mtremor++;
  1028. return 0;
  1029. }
  1030. static int DoS3MEffectQ(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
  1031. {
  1032. UBYTE inf;
  1033. inf = UniGetByte();
  1034. if (a->main.period) {
  1035. if (inf) {
  1036. a->s3mrtgslide=inf>>4;
  1037. a->s3mrtgspeed=inf&0xf;
  1038. }
  1039. /* only retrigger if low nibble > 0 */
  1040. if (a->s3mrtgspeed>0) {
  1041. if (!a->retrig) {
  1042. /* when retrig counter reaches 0, reset counter and restart the
  1043.    sample */
  1044. if (a->main.kick!=KICK_NOTE) a->main.kick=KICK_KEYOFF;
  1045. a->retrig=a->s3mrtgspeed;
  1046. if ((tick)||(flags&UF_S3MSLIDES)) {
  1047. switch (a->s3mrtgslide) {
  1048. case 1:
  1049. case 2:
  1050. case 3:
  1051. case 4:
  1052. case 5:
  1053. a->tmpvolume-=(1<<(a->s3mrtgslide-1));
  1054. break;
  1055. case 6:
  1056. a->tmpvolume=(2*a->tmpvolume)/3;
  1057. break;
  1058. case 7:
  1059. a->tmpvolume>>=1;
  1060. break;
  1061. case 9:
  1062. case 0xa:
  1063. case 0xb:
  1064. case 0xc:
  1065. case 0xd:
  1066. a->tmpvolume+=(1<<(a->s3mrtgslide-9));
  1067. break;
  1068. case 0xe:
  1069. a->tmpvolume=(3*a->tmpvolume)>>1;
  1070. break;
  1071. case 0xf:
  1072. a->tmpvolume=a->tmpvolume<<1;
  1073. break;
  1074. }
  1075. if (a->tmpvolume<0)
  1076. a->tmpvolume=0;
  1077. else if (a->tmpvolume>64)
  1078. a->tmpvolume=64;
  1079. }
  1080. }
  1081. a->retrig--; /* countdown  */
  1082. }
  1083. }
  1084. return 0;
  1085. }
  1086. static int DoS3MEffectR(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
  1087. {
  1088. UBYTE dat, q;
  1089. UWORD temp=0; /* silence warning */
  1090. dat = UniGetByte();
  1091. if (!tick) {
  1092. if (dat&0x0f) a->trmdepth=dat&0xf;
  1093. if (dat&0xf0) a->trmspd=(dat&0xf0)>>2;
  1094. }
  1095. q=(a->trmpos>>2)&0x1f;
  1096. switch ((a->wavecontrol>>4)&3) {
  1097. case 0: /* sine */
  1098. temp=VibratoTable[q];
  1099. break;
  1100. case 1: /* ramp down */
  1101. q<<=3;
  1102. if (a->trmpos<0) q=255-q;
  1103. temp=q;
  1104. break;
  1105. case 2: /* square wave */
  1106. temp=255;
  1107. break;
  1108. case 3: /* random */
  1109. temp=getrandom(256);
  1110. break;
  1111. }
  1112. temp*=a->trmdepth;
  1113. temp>>=7;
  1114. if (a->trmpos>=0) {
  1115. a->volume=a->tmpvolume+temp;
  1116. if (a->volume>64) a->volume=64;
  1117. } else {
  1118. a->volume=a->tmpvolume-temp;
  1119. if (a->volume<0) a->volume=0;
  1120. }
  1121. a->ownvol = 1;
  1122. if (tick)
  1123. a->trmpos+=a->trmspd;
  1124. return 0;
  1125. }
  1126. static int DoS3MEffectT(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
  1127. {
  1128. UBYTE tempo;
  1129. tempo = UniGetByte();
  1130. if (tick || mod->patdly2)
  1131. return 0;
  1132. mod->bpm = (tempo < 32) ? 32 : tempo;
  1133. return 0;
  1134. }
  1135. static int DoS3MEffectU(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
  1136. {
  1137. UBYTE dat, q;
  1138. UWORD temp = 0; /* silence warning */
  1139. dat = UniGetByte();
  1140. if (!tick) {
  1141. if (dat&0x0f) a->vibdepth=dat&0xf;
  1142. if (dat&0xf0) a->vibspd=(dat&0xf0)>>2;
  1143. } else
  1144. if (a->main.period) {
  1145. q=(a->vibpos>>2)&0x1f;
  1146. switch (a->wavecontrol&3) {
  1147. case 0: /* sine */
  1148. temp=VibratoTable[q];
  1149. break;
  1150. case 1: /* ramp down */
  1151. q<<=3;
  1152. if (a->vibpos<0) q=255-q;
  1153. temp=q;
  1154. break;
  1155. case 2: /* square wave */
  1156. temp=255;
  1157. break;
  1158. case 3: /* random */
  1159. temp=getrandom(256);
  1160. break;
  1161. }
  1162. temp*=a->vibdepth;
  1163. temp>>=8;
  1164. if (a->vibpos>=0)
  1165. a->main.period=a->tmpperiod+temp;
  1166. else
  1167. a->main.period=a->tmpperiod-temp;
  1168. a->ownper = 1;
  1169. a->vibpos+=a->vibspd;
  1170. }
  1171. return 0;
  1172. }
  1173. /*========== Envelope helpers */
  1174. static int DoKeyOff(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
  1175. {
  1176. a->main.keyoff|=KEY_OFF;
  1177. if ((!(a->main.volflg&EF_ON))||(a->main.volflg&EF_LOOP))
  1178. a->main.keyoff=KEY_KILL;
  1179. return 0;
  1180. }
  1181. static int DoKeyFade(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
  1182. {
  1183. UBYTE dat;
  1184. dat=UniGetByte();
  1185. if ((tick>=dat)||(tick==mod->sngspd-1)) {
  1186. a->main.keyoff=KEY_KILL;
  1187. if (!(a->main.volflg&EF_ON))
  1188. a->main.fadevol=0;
  1189. }
  1190. return 0;
  1191. }
  1192. /*========== Fast Tracker effects */
  1193. /* DoXMEffect6 after DoXMEffectA */
  1194. static int DoXMEffectA(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
  1195. {
  1196. UBYTE inf, lo, hi;
  1197. inf = UniGetByte();
  1198. if (inf)
  1199. a->s3mvolslide = inf;
  1200. else
  1201. inf = a->s3mvolslide;
  1202. if (tick) {
  1203. lo=inf&0xf;
  1204. hi=inf>>4;
  1205. if (!hi) {
  1206. a->tmpvolume-=lo;
  1207. if (a->tmpvolume<0) a->tmpvolume=0;
  1208. } else {
  1209. a->tmpvolume+=hi;
  1210. if (a->tmpvolume>64) a->tmpvolume=64;
  1211. }
  1212. }
  1213. return 0;
  1214. }
  1215. static int DoXMEffect6(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
  1216. {
  1217. if (a->main.period)
  1218. DoVibrato(tick, a);
  1219. return DoXMEffectA(tick, flags, a, mod, channel);
  1220. }
  1221. static int DoXMEffectE1(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
  1222. {
  1223. UBYTE dat;
  1224. dat=UniGetByte();
  1225. if (!tick) {
  1226. if (dat) a->fportupspd=dat;
  1227. if (a->main.period)
  1228. a->tmpperiod-=(a->fportupspd<<2);
  1229. }
  1230. return 0;
  1231. }
  1232. static int DoXMEffectE2(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
  1233. {
  1234. UBYTE dat;
  1235. dat=UniGetByte();
  1236. if (!tick) {
  1237. if (dat) a->fportdnspd=dat;
  1238. if (a->main.period)
  1239. a->tmpperiod+=(a->fportdnspd<<2);
  1240. }
  1241. return 0;
  1242. }
  1243. static int DoXMEffectEA(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
  1244. {
  1245. UBYTE dat;
  1246. dat=UniGetByte();
  1247. if (!tick)
  1248. if (dat) a->fslideupspd=dat;
  1249. a->tmpvolume+=a->fslideupspd;
  1250. if (a->tmpvolume>64) a->tmpvolume=64;
  1251. return 0;
  1252. }
  1253. static int DoXMEffectEB(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
  1254. {
  1255. UBYTE dat;
  1256. dat=UniGetByte();
  1257. if (!tick)
  1258. if (dat) a->fslidednspd=dat;
  1259. a->tmpvolume-=a->fslidednspd;
  1260. if (a->tmpvolume<0) a->tmpvolume=0;
  1261. return 0;
  1262. }
  1263. static int DoXMEffectG(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
  1264. {
  1265. mod->volume=UniGetByte()<<1;
  1266. if (mod->volume>128) mod->volume=128;
  1267. return 0;
  1268. }
  1269. static int DoXMEffectH(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
  1270. {
  1271. UBYTE inf;
  1272. inf = UniGetByte();
  1273. if (tick) {
  1274. if (inf) mod->globalslide=inf;
  1275. else inf=mod->globalslide;
  1276. if (inf & 0xf0) inf&=0xf0;
  1277. mod->volume=mod->volume+((inf>>4)-(inf&0xf))*2;
  1278. if (mod->volume<0)
  1279. mod->volume=0;
  1280. else if (mod->volume>128)
  1281. mod->volume=128;
  1282. }
  1283. return 0;
  1284. }
  1285. static int DoXMEffectL(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
  1286. {
  1287. UBYTE dat;
  1288. dat=UniGetByte();
  1289. if ((!tick)&&(a->main.i)) {
  1290. UWORD points;
  1291. INSTRUMENT *i=a->main.i;
  1292. MP_VOICE *aout;
  1293. if ((aout=a->slave)) {
  1294. if (aout->venv.env) {
  1295. points=i->volenv[i->volpts-1].pos;
  1296. aout->venv.p=aout->venv.env[(dat>points)?points:dat].pos;
  1297. }
  1298. if (aout->penv.env) {
  1299. points=i->panenv[i->panpts-1].pos;
  1300. aout->penv.p=aout->penv.env[(dat>points)?points:dat].pos;
  1301. }
  1302. }
  1303. }
  1304. return 0;
  1305. }
  1306. static int DoXMEffectP(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
  1307. {
  1308. UBYTE inf, lo, hi;
  1309. SWORD pan;
  1310. inf = UniGetByte();
  1311. if (!mod->panflag)
  1312. return 0;
  1313. if (inf)
  1314. a->pansspd = inf;
  1315. else
  1316. inf =a->pansspd;
  1317. if (tick) {
  1318. lo=inf&0xf;
  1319. hi=inf>>4;
  1320. /* slide right has absolute priority */
  1321. if (hi)
  1322. lo = 0;
  1323. pan=((a->main.panning==PAN_SURROUND)?PAN_CENTER:a->main.panning)+hi-lo;
  1324. a->main.panning=(pan<PAN_LEFT)?PAN_LEFT:(pan>PAN_RIGHT?PAN_RIGHT:pan);
  1325. }
  1326. return 0;
  1327. }
  1328. static int DoXMEffectX1(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
  1329. {
  1330. UBYTE dat;
  1331. dat = UniGetByte();
  1332. if (dat)
  1333. a->ffportupspd = dat;
  1334. else
  1335. dat = a->ffportupspd;
  1336. if (a->main.period)
  1337. if (!tick) {
  1338. a->main.period-=dat;
  1339. a->tmpperiod-=dat;
  1340. a->ownper = 1;
  1341. }
  1342. return 0;
  1343. }
  1344. static int DoXMEffectX2(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
  1345. {
  1346. UBYTE dat;
  1347. dat = UniGetByte();
  1348. if (dat)
  1349. a->ffportdnspd=dat;
  1350. else
  1351. dat = a->ffportdnspd;
  1352. if (a->main.period)
  1353. if (!tick) {
  1354. a->main.period+=dat;
  1355. a->tmpperiod+=dat;
  1356. a->ownper = 1;
  1357. }
  1358. return 0;
  1359. }
  1360. /*========== Impulse Tracker effects */
  1361. static void DoITToneSlide(UWORD tick, MP_CONTROL *a, UBYTE dat)
  1362. {
  1363. if (dat)
  1364. a->portspeed = dat;
  1365. /* if we don't come from another note, ignore the slide and play the note
  1366.    as is */
  1367. if (!a->oldnote || !a->main.period)
  1368. return;
  1369. if ((!tick)&&(a->newsamp)){
  1370. a->main.kick=KICK_NOTE;
  1371. a->main.start=-1;
  1372. } else
  1373. a->main.kick=(a->main.kick==KICK_NOTE)?KICK_ENV:KICK_ABSENT;
  1374. if (tick) {
  1375. int dist;
  1376. /* We have to slide a->main.period towards a->wantedperiod, compute the
  1377.    difference between those two values */
  1378. dist=a->main.period-a->wantedperiod;
  1379.     /* if they are equal or if portamentospeed is too big... */
  1380. if ((!dist)||((a->portspeed<<2)>abs(dist)))
  1381. /* ... make tmpperiod equal tperiod */
  1382. a->tmpperiod=a->main.period=a->wantedperiod;
  1383. else
  1384.   if (dist>0) {
  1385. a->tmpperiod-=a->portspeed<<2;
  1386. a->main.period-=a->portspeed<<2; /* dist>0 slide up */
  1387. } else {
  1388. a->tmpperiod+=a->portspeed<<2;
  1389. a->main.period+=a->portspeed<<2; /* dist<0 slide down */
  1390. }
  1391. } else
  1392. a->tmpperiod=a->main.period;
  1393. a->ownper=1;
  1394. }
  1395. static int DoITEffectG(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
  1396. {
  1397. DoITToneSlide(tick, a, UniGetByte());
  1398. return 0;
  1399. }
  1400. static void DoITVibrato(UWORD tick, MP_CONTROL *a, UBYTE dat)
  1401. {
  1402. UBYTE q;
  1403. UWORD temp=0;
  1404. if (!tick) {
  1405. if (dat&0x0f) a->vibdepth=dat&0xf;
  1406. if (dat&0xf0) a->vibspd=(dat&0xf0)>>2;
  1407. }
  1408. if (!a->main.period)
  1409. return;
  1410. q=(a->vibpos>>2)&0x1f;
  1411. switch (a->wavecontrol&3) {
  1412. case 0: /* sine */
  1413. temp=VibratoTable[q];
  1414. break;
  1415. case 1: /* square wave */
  1416. temp=255;
  1417. break;
  1418. case 2: /* ramp down */
  1419. q<<=3;
  1420. if (a->vibpos<0) q=255-q;
  1421. temp=q;
  1422. break;
  1423. case 3: /* random */
  1424. temp=getrandom(256);
  1425. break;
  1426. }
  1427. temp*=a->vibdepth;
  1428. temp>>=8;
  1429. temp<<=2;
  1430. if (a->vibpos>=0)
  1431. a->main.period=a->tmpperiod+temp;
  1432. else
  1433. a->main.period=a->tmpperiod-temp;
  1434. a->ownper=1;
  1435. a->vibpos+=a->vibspd;
  1436. }
  1437. static int DoITEffectH(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
  1438. {
  1439. DoITVibrato(tick, a, UniGetByte());
  1440. return 0;
  1441. }
  1442. static int DoITEffectI(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
  1443. {
  1444. UBYTE inf, on, off;
  1445. inf = UniGetByte();
  1446. if (inf)
  1447. a->s3mtronof = inf;
  1448. else {
  1449. inf = a->s3mtronof;
  1450. if (!inf)
  1451. return 0;
  1452. }
  1453. on=(inf>>4);
  1454. off=(inf&0xf);
  1455. a->s3mtremor%=(on+off);
  1456. a->volume=(a->s3mtremor<on)?a->tmpvolume:0;
  1457. a->ownvol = 1;
  1458. a->s3mtremor++;
  1459. return 0;
  1460. }
  1461. static int DoITEffectM(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
  1462. {
  1463. a->main.chanvol=UniGetByte();
  1464. if (a->main.chanvol>64)
  1465. a->main.chanvol=64;
  1466. else if (a->main.chanvol<0)
  1467. a->main.chanvol=0;
  1468. return 0;
  1469. }
  1470. static int DoITEffectN(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
  1471. {
  1472. UBYTE inf, lo, hi;
  1473. inf = UniGetByte();
  1474. if (inf)
  1475. a->chanvolslide = inf;
  1476. else
  1477. inf = a->chanvolslide;
  1478. lo=inf&0xf;
  1479. hi=inf>>4;
  1480. if (!hi) 
  1481. a->main.chanvol-=lo;
  1482. else
  1483.   if (!lo) {
  1484. a->main.chanvol+=hi;
  1485. } else
  1486.   if (hi==0xf) {
  1487. if (!tick) a->main.chanvol-=lo;
  1488. } else
  1489.   if (lo==0xf) {
  1490. if (!tick) a->main.chanvol+=hi;
  1491. }
  1492. if (a->main.chanvol<0)
  1493. a->main.chanvol=0;
  1494. else if (a->main.chanvol>64)
  1495. a->main.chanvol=64;
  1496. return 0;
  1497. }
  1498. static int DoITEffectP(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
  1499. {
  1500. UBYTE inf, lo, hi;
  1501. SWORD pan;
  1502. inf = UniGetByte();
  1503. if (inf)
  1504. a->pansspd = inf;
  1505. else
  1506. inf = a->pansspd;
  1507. if (!mod->panflag)
  1508. return 0;
  1509. lo=inf&0xf;
  1510. hi=inf>>4;
  1511. pan=(a->main.panning==PAN_SURROUND)?PAN_CENTER:a->main.panning;
  1512. if (!hi)
  1513. pan+=lo<<2;
  1514. else
  1515.   if (!lo) {
  1516. pan-=hi<<2;
  1517. } else
  1518.   if (hi==0xf) {
  1519. if (!tick) pan+=lo<<2;
  1520. } else
  1521.   if (lo==0xf) {
  1522. if (!tick) pan-=hi<<2;
  1523. }
  1524. a->main.panning=
  1525.   (pan<PAN_LEFT)?PAN_LEFT:(pan>PAN_RIGHT?PAN_RIGHT:pan);
  1526. return 0;
  1527. }
  1528. static int DoITEffectT(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
  1529. {
  1530. UBYTE tempo;
  1531. SWORD temp;
  1532.     tempo = UniGetByte();
  1533. if (mod->patdly2)
  1534. return 0;
  1535. temp = mod->bpm;
  1536. if (tempo & 0x10)
  1537. temp += (tempo & 0x0f);
  1538. else
  1539. temp -= tempo;
  1540. mod->bpm=(temp>255)?255:(temp<1?1:temp);
  1541. return 0;
  1542. }
  1543. static int DoITEffectU(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
  1544. {
  1545. UBYTE dat, q;
  1546. UWORD temp = 0; /* silence warning */
  1547. dat = UniGetByte();
  1548. if (!tick) {
  1549. if (dat&0x0f) a->vibdepth=dat&0xf;
  1550. if (dat&0xf0) a->vibspd=(dat&0xf0)>>2;
  1551. }
  1552. if (a->main.period) {
  1553. q=(a->vibpos>>2)&0x1f;
  1554. switch (a->wavecontrol&3) {
  1555. case 0: /* sine */
  1556. temp=VibratoTable[q];
  1557. break;
  1558. case 1: /* square wave */
  1559. temp=255;
  1560. break;
  1561. case 2: /* ramp down */
  1562. q<<=3;
  1563. if (a->vibpos<0) q=255-q;
  1564. temp=q;
  1565. break;
  1566. case 3: /* random */
  1567. temp=getrandom(256);
  1568. break;
  1569. }
  1570. temp*=a->vibdepth;
  1571. temp>>=8;
  1572. if (a->vibpos>=0)
  1573. a->main.period=a->tmpperiod+temp;
  1574. else
  1575. a->main.period=a->tmpperiod-temp;
  1576. a->ownper = 1;
  1577. a->vibpos+=a->vibspd;
  1578. }
  1579. return 0;
  1580. }
  1581. static int DoITEffectW(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
  1582. {
  1583. UBYTE inf, lo, hi;
  1584. inf = UniGetByte();
  1585. if (inf)
  1586. mod->globalslide = inf;
  1587. else
  1588. inf = mod->globalslide;
  1589. lo=inf&0xf;
  1590. hi=inf>>4;
  1591. if (!lo) {
  1592. if (tick) mod->volume+=hi;
  1593. } else
  1594.   if (!hi) {
  1595. if (tick) mod->volume-=lo;
  1596. } else
  1597.   if (lo==0xf) {
  1598. if (!tick) mod->volume+=hi;
  1599. } else
  1600.   if (hi==0xf) {
  1601. if (!tick) mod->volume-=lo;
  1602. }
  1603. if (mod->volume<0)
  1604. mod->volume=0;
  1605. else if (mod->volume>128)
  1606. mod->volume=128;
  1607. return 0;
  1608. }
  1609. static int DoITEffectY(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
  1610. {
  1611. UBYTE dat, q;
  1612. SLONG temp = 0; /* silence warning */
  1613. dat=UniGetByte();
  1614. if (!tick) {
  1615. if (dat&0x0f) a->panbdepth=(dat&0xf);
  1616. if (dat&0xf0) a->panbspd=(dat&0xf0)>>4;
  1617. }
  1618. if (mod->panflag) {
  1619. q=a->panbpos;
  1620. switch (a->panbwave) {
  1621. case 0: /* sine */
  1622. temp=PanbrelloTable[q];
  1623. break;
  1624. case 1: /* square wave */
  1625. temp=(q<0x80)?64:0;
  1626. break;
  1627. case 2: /* ramp down */
  1628. q<<=3;
  1629. temp=q;
  1630. break;
  1631. case 3: /* random */
  1632. temp=getrandom(256);
  1633. break;
  1634. }
  1635. temp*=a->panbdepth;
  1636. temp=(temp/8)+mod->panning[channel];
  1637. a->main.panning=
  1638. (temp<PAN_LEFT)?PAN_LEFT:(temp>PAN_RIGHT?PAN_RIGHT:temp);
  1639. a->panbpos+=a->panbspd;
  1640. }
  1641. return 0;
  1642. }
  1643. static void DoNNAEffects(MODULE *, MP_CONTROL *, UBYTE);
  1644. /* Impulse/Scream Tracker Sxx effects.
  1645.    All Sxx effects share the same memory space. */
  1646. static int DoITEffectS0(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
  1647. {
  1648. UBYTE dat, inf, c;
  1649. dat = UniGetByte();
  1650. inf=dat&0xf;
  1651. c=dat>>4;
  1652. if (!dat) {
  1653. c=a->sseffect;
  1654. inf=a->ssdata;
  1655. } else {
  1656. a->sseffect=c;
  1657. a->ssdata=inf;
  1658. }
  1659. switch (c) {
  1660. case SS_GLISSANDO: /* S1x set glissando voice */
  1661. DoEEffects(tick, flags, a, mod, channel, 0x30|inf);
  1662. break;              
  1663. case SS_FINETUNE: /* S2x set finetune */
  1664. DoEEffects(tick, flags, a, mod, channel, 0x50|inf);
  1665. break;
  1666. case SS_VIBWAVE: /* S3x set vibrato waveform */
  1667. DoEEffects(tick, flags, a, mod, channel, 0x40|inf);
  1668. break;   
  1669. case SS_TREMWAVE: /* S4x set tremolo waveform */
  1670. DoEEffects(tick, flags, a, mod, channel, 0x70|inf);
  1671. break;
  1672. case SS_PANWAVE: /* S5x panbrello */
  1673. a->panbwave=inf;
  1674. break;
  1675. case SS_FRAMEDELAY: /* S6x delay x number of frames (patdly) */
  1676. DoEEffects(tick, flags, a, mod, channel, 0xe0|inf);
  1677. break;
  1678. case SS_S7EFFECTS: /* S7x instrument / NNA commands */
  1679. DoNNAEffects(mod, a, inf);
  1680. break;
  1681. case SS_PANNING: /* S8x set panning position */
  1682. DoEEffects(tick, flags, a, mod, channel, 0x80 | inf);
  1683. break;
  1684. case SS_SURROUND: /* S9x set surround sound */
  1685. if (mod->panflag)
  1686. a->main.panning = mod->panning[channel] = PAN_SURROUND;
  1687. break;    
  1688. case SS_HIOFFSET: /* SAy set high order sample offset yxx00h */
  1689. if (!tick) {
  1690. a->hioffset=inf<<16;
  1691. a->main.start=a->hioffset|a->soffset;
  1692. if ((a->main.s)&&(a->main.start>a->main.s->length))
  1693. a->main.start=a->main.s->flags&(SF_LOOP|SF_BIDI)?
  1694.     a->main.s->loopstart:a->main.s->length;
  1695. }
  1696. break;
  1697. case SS_PATLOOP: /* SBx pattern loop */
  1698. DoEEffects(tick, flags, a, mod, channel, 0x60|inf);
  1699. break;
  1700. case SS_NOTECUT: /* SCx notecut */
  1701. if (!inf) inf = 1;
  1702. DoEEffects(tick, flags, a, mod, channel, 0xC0|inf);
  1703. break;
  1704. case SS_NOTEDELAY: /* SDx notedelay */
  1705. DoEEffects(tick, flags, a, mod, channel, 0xD0|inf);
  1706. break;
  1707. case SS_PATDELAY: /* SEx patterndelay */
  1708. DoEEffects(tick, flags, a, mod, channel, 0xE0|inf);
  1709. break;
  1710. }
  1711. return 0;
  1712. }
  1713. /*========== Impulse Tracker Volume/Pan Column effects */
  1714. /*
  1715.  * All volume/pan column effects share the same memory space.
  1716.  */
  1717. static int DoVolEffects(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
  1718. {
  1719. UBYTE c, inf;
  1720. c = UniGetByte(); 
  1721. inf = UniGetByte(); 
  1722. if ((!c)&&(!inf)) {
  1723. c=a->voleffect;
  1724. inf=a->voldata;
  1725. } else {
  1726. a->voleffect=c;
  1727. a->voldata=inf;
  1728. }
  1729. if (c)
  1730. switch (c) {
  1731. case VOL_VOLUME:
  1732. if (tick) break;
  1733. if (inf>64) inf=64;
  1734. a->tmpvolume=inf;
  1735. break;
  1736. case VOL_PANNING:
  1737. if (mod->panflag)
  1738. a->main.panning=inf;
  1739. break;
  1740. case VOL_VOLSLIDE:
  1741. DoS3MVolSlide(tick, flags, a, inf);
  1742. return 1;
  1743. case VOL_PITCHSLIDEDN:
  1744. if (a->main.period)
  1745. DoS3MSlideDn(tick, a, inf);
  1746. break;
  1747. case VOL_PITCHSLIDEUP:
  1748. if (a->main.period)
  1749. DoS3MSlideUp(tick, a, inf);
  1750. break;
  1751. case VOL_PORTAMENTO:
  1752. DoITToneSlide(tick, a, inf);
  1753. break;
  1754. case VOL_VIBRATO:
  1755. DoITVibrato(tick, a, inf);
  1756. break;
  1757. }
  1758. return 0;
  1759. }
  1760. /*========== UltraTracker effects */
  1761. static int DoULTEffect9(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
  1762. {
  1763. UWORD offset=UniGetWord();
  1764. if (offset)
  1765. a->ultoffset=offset;
  1766. a->main.start=a->ultoffset<<2;
  1767. if ((a->main.s)&&(a->main.start>a->main.s->length))
  1768. a->main.start=a->main.s->flags&(SF_LOOP|SF_BIDI)?
  1769.     a->main.s->loopstart:a->main.s->length;
  1770. return 0;
  1771. }
  1772. /*========== OctaMED effects */
  1773. static int DoMEDSpeed(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
  1774. {
  1775. UWORD speed=UniGetWord();
  1776. mod->bpm=speed;
  1777. return 0;
  1778. }
  1779. static int DoMEDEffectF1(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
  1780. {
  1781. DoEEffects(tick, flags, a, mod, channel, 0x90|(mod->sngspd/2));
  1782. return 0;
  1783. }
  1784. static int DoMEDEffectF2(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
  1785. {
  1786. DoEEffects(tick, flags, a, mod, channel, 0xd0|(mod->sngspd/2));
  1787. return 0;
  1788. }
  1789. static int DoMEDEffectF3(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
  1790. {
  1791. DoEEffects(tick, flags, a, mod, channel, 0x90|(mod->sngspd/3));
  1792. return 0;
  1793. }
  1794. /*========== Oktalyzer effects */
  1795. static int DoOktArp(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
  1796. {
  1797. UBYTE dat, dat2;
  1798. dat2 = UniGetByte(); /* arpeggio style */
  1799. dat = UniGetByte();
  1800. if (!tick) {
  1801. if (!dat && (flags & UF_ARPMEM))
  1802. dat=a->arpmem;
  1803. else
  1804. a->arpmem=dat;
  1805. }
  1806. if (a->main.period)
  1807. DoArpeggio(tick, flags, a, dat2);
  1808. return 0;
  1809. }
  1810. /*========== General player functions */
  1811. static int DoNothing(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel)
  1812. {
  1813. UniSkipOpcode();
  1814. return 0;
  1815. }
  1816. typedef int (*effect_func) (UWORD, UWORD, MP_CONTROL *, MODULE *, SWORD);
  1817. static effect_func effects[UNI_LAST] = {
  1818. DoNothing, /* 0 */
  1819. DoNothing, /* UNI_NOTE */
  1820. DoNothing, /* UNI_INSTRUMENT */
  1821. DoPTEffect0, /* UNI_PTEFFECT0 */
  1822. DoPTEffect1, /* UNI_PTEFFECT1 */
  1823. DoPTEffect2, /* UNI_PTEFFECT2 */
  1824. DoPTEffect3, /* UNI_PTEFFECT3 */
  1825. DoPTEffect4, /* UNI_PTEFFECT4 */
  1826. DoPTEffect5, /* UNI_PTEFFECT5 */
  1827. DoPTEffect6, /* UNI_PTEFFECT6 */
  1828. DoPTEffect7, /* UNI_PTEFFECT7 */
  1829. DoPTEffect8, /* UNI_PTEFFECT8 */
  1830. DoPTEffect9, /* UNI_PTEFFECT9 */
  1831. DoPTEffectA, /* UNI_PTEFFECTA */
  1832. DoPTEffectB, /* UNI_PTEFFECTB */
  1833. DoPTEffectC, /* UNI_PTEFFECTC */
  1834. DoPTEffectD, /* UNI_PTEFFECTD */
  1835. DoPTEffectE, /* UNI_PTEFFECTE */
  1836. DoPTEffectF, /* UNI_PTEFFECTF */
  1837. DoS3MEffectA, /* UNI_S3MEFFECTA */
  1838. DoS3MEffectD, /* UNI_S3MEFFECTD */
  1839. DoS3MEffectE, /* UNI_S3MEFFECTE */
  1840. DoS3MEffectF, /* UNI_S3MEFFECTF */
  1841. DoS3MEffectI, /* UNI_S3MEFFECTI */
  1842. DoS3MEffectQ, /* UNI_S3MEFFECTQ */
  1843. DoS3MEffectR, /* UNI_S3MEFFECTR */
  1844. DoS3MEffectT, /* UNI_S3MEFFECTT */
  1845. DoS3MEffectU, /* UNI_S3MEFFECTU */
  1846. DoKeyOff, /* UNI_KEYOFF */
  1847. DoKeyFade, /* UNI_KEYFADE */
  1848. DoVolEffects, /* UNI_VOLEFFECTS */
  1849. DoPTEffect4, /* UNI_XMEFFECT4 */
  1850. DoXMEffect6, /* UNI_XMEFFECT6 */
  1851. DoXMEffectA, /* UNI_XMEFFECTA */
  1852. DoXMEffectE1, /* UNI_XMEFFECTE1 */
  1853. DoXMEffectE2, /* UNI_XMEFFECTE2 */
  1854. DoXMEffectEA, /* UNI_XMEFFECTEA */
  1855. DoXMEffectEB, /* UNI_XMEFFECTEB */
  1856. DoXMEffectG, /* UNI_XMEFFECTG */
  1857. DoXMEffectH, /* UNI_XMEFFECTH */
  1858. DoXMEffectL, /* UNI_XMEFFECTL */
  1859. DoXMEffectP, /* UNI_XMEFFECTP */
  1860. DoXMEffectX1, /* UNI_XMEFFECTX1 */
  1861. DoXMEffectX2, /* UNI_XMEFFECTX2 */
  1862. DoITEffectG, /* UNI_ITEFFECTG */
  1863. DoITEffectH, /* UNI_ITEFFECTH */
  1864. DoITEffectI, /* UNI_ITEFFECTI */
  1865. DoITEffectM, /* UNI_ITEFFECTM */
  1866. DoITEffectN, /* UNI_ITEFFECTN */
  1867. DoITEffectP, /* UNI_ITEFFECTP */
  1868. DoITEffectT, /* UNI_ITEFFECTT */
  1869. DoITEffectU, /* UNI_ITEFFECTU */
  1870. DoITEffectW, /* UNI_ITEFFECTW */
  1871. DoITEffectY, /* UNI_ITEFFECTY */
  1872. DoNothing, /* UNI_ITEFFECTZ */
  1873. DoITEffectS0, /* UNI_ITEFFECTS0 */
  1874. DoULTEffect9, /* UNI_ULTEFFECT9 */
  1875. DoMEDSpeed, /* UNI_MEDSPEED */
  1876. DoMEDEffectF1, /* UNI_MEDEFFECTF1 */
  1877. DoMEDEffectF2, /* UNI_MEDEFFECTF2 */
  1878. DoMEDEffectF3, /* UNI_MEDEFFECTF3 */
  1879. DoOktArp, /* UNI_OKTARP */
  1880. };
  1881. static int pt_playeffects(MODULE *mod, SWORD channel, MP_CONTROL *a)
  1882. {
  1883. UWORD tick = mod->vbtick;
  1884. UWORD flags = mod->flags;
  1885. UBYTE c;
  1886. int explicitslides = 0;
  1887. effect_func f;
  1888. while((c=UniGetByte())) {
  1889. f = effects[c];
  1890. if (f != DoNothing)
  1891. a->sliding = 0;
  1892. explicitslides |= f(tick, flags, a, mod, channel);
  1893. }
  1894. return explicitslides;
  1895. }
  1896. static void DoNNAEffects(MODULE *mod, MP_CONTROL *a, UBYTE dat)
  1897. {
  1898. int t;
  1899. MP_VOICE *aout;
  1900. dat&=0xf; 
  1901. aout=(a->slave)?a->slave:NULL;
  1902. switch (dat) {
  1903. case 0x0: /* past note cut */
  1904. for (t=0;t<md_sngchn;t++)
  1905. if (mod->voice[t].master==a)
  1906. mod->voice[t].main.fadevol=0;
  1907. break;
  1908. case 0x1: /* past note off */
  1909. for (t=0;t<md_sngchn;t++)
  1910. if (mod->voice[t].master==a) {
  1911. mod->voice[t].main.keyoff|=KEY_OFF;
  1912. if ((!(mod->voice[t].venv.flg & EF_ON))||
  1913.    (mod->voice[t].venv.flg & EF_LOOP))
  1914. mod->voice[t].main.keyoff=KEY_KILL;
  1915. }
  1916. break;
  1917. case 0x2: /* past note fade */
  1918. for (t=0;t<md_sngchn;t++)
  1919. if (mod->voice[t].master==a)
  1920. mod->voice[t].main.keyoff|=KEY_FADE;
  1921. break;
  1922. case 0x3: /* set NNA note cut */
  1923. a->main.nna=(a->main.nna&~NNA_MASK)|NNA_CUT;
  1924. break;
  1925. case 0x4: /* set NNA note continue */
  1926. a->main.nna=(a->main.nna&~NNA_MASK)|NNA_CONTINUE;
  1927. break;
  1928. case 0x5: /* set NNA note off */
  1929. a->main.nna=(a->main.nna&~NNA_MASK)|NNA_OFF;
  1930. break;   
  1931. case 0x6: /* set NNA note fade */
  1932. a->main.nna=(a->main.nna&~NNA_MASK)|NNA_FADE;
  1933. break;
  1934. case 0x7: /* disable volume envelope */
  1935. if (aout)
  1936. aout->main.volflg&=~EF_ON;
  1937. break;
  1938. case 0x8: /* enable volume envelope  */
  1939. if (aout)
  1940. aout->main.volflg|=EF_ON;
  1941. break;
  1942. case 0x9: /* disable panning envelope */
  1943. if (aout)
  1944. aout->main.panflg&=~EF_ON;
  1945. break;    
  1946. case 0xa: /* enable panning envelope */
  1947. if (aout)
  1948. aout->main.panflg|=EF_ON;
  1949. break;
  1950. case 0xb: /* disable pitch envelope */
  1951. if (aout)
  1952. aout->main.pitflg&=~EF_ON;
  1953. break;
  1954. case 0xc: /* enable pitch envelope */
  1955. if (aout)
  1956. aout->main.pitflg|=EF_ON;
  1957. break;
  1958. }
  1959. }
  1960. void pt_UpdateVoices(MODULE *mod, int max_volume)
  1961. {
  1962. SWORD envpan,envvol,envpit,channel;
  1963. UWORD playperiod;
  1964. SLONG vibval,vibdpt;
  1965. ULONG tmpvol;
  1966. MP_VOICE *aout;
  1967. INSTRUMENT *i;
  1968. SAMPLE *s;
  1969. mod->totalchn=mod->realchn=0;
  1970. for (channel=0;channel<md_sngchn;channel++) {
  1971. aout=&mod->voice[channel];
  1972. i=aout->main.i;
  1973. s=aout->main.s;
  1974. if (!s || !s->length) continue;
  1975. if (aout->main.period<40)
  1976. aout->main.period=40;
  1977. else if (aout->main.period>50000)
  1978. aout->main.period=50000;
  1979. if ((aout->main.kick==KICK_NOTE)||(aout->main.kick==KICK_KEYOFF)) {
  1980. Voice_Play_internal(channel,s,(aout->main.start==-1)?
  1981.     ((s->flags&SF_UST_LOOP)?s->loopstart:0):aout->main.start);
  1982. aout->main.fadevol=32768;
  1983. aout->aswppos=0;
  1984. }
  1985. envvol = 256;
  1986. envpan = PAN_CENTER;
  1987. envpit = 32;
  1988. if (i && ((aout->main.kick==KICK_NOTE)||(aout->main.kick==KICK_ENV))) {
  1989. if (aout->main.volflg & EF_ON)
  1990. envvol = StartEnvelope(&aout->venv,aout->main.volflg,
  1991.   i->volpts,i->volsusbeg,i->volsusend,
  1992.   i->volbeg,i->volend,i->volenv,aout->main.keyoff);
  1993. if (aout->main.panflg & EF_ON)
  1994. envpan = StartEnvelope(&aout->penv,aout->main.panflg,
  1995.   i->panpts,i->pansusbeg,i->pansusend,
  1996.   i->panbeg,i->panend,i->panenv,aout->main.keyoff);
  1997. if (aout->main.pitflg & EF_ON)
  1998. envpit = StartEnvelope(&aout->cenv,aout->main.pitflg,
  1999.   i->pitpts,i->pitsusbeg,i->pitsusend,
  2000.   i->pitbeg,i->pitend,i->pitenv,aout->main.keyoff);
  2001. if (aout->cenv.flg & EF_ON)
  2002. aout->masterperiod=GetPeriod(mod->flags,
  2003.   (UWORD)aout->main.note<<1, aout->master->speed);
  2004. } else {
  2005. if (aout->main.volflg & EF_ON)
  2006. envvol = ProcessEnvelope(aout,&aout->venv,256);
  2007. if (aout->main.panflg & EF_ON)
  2008. envpan = ProcessEnvelope(aout,&aout->penv,PAN_CENTER);
  2009. if (aout->main.pitflg & EF_ON)
  2010. envpit = ProcessEnvelope(aout,&aout->cenv,32);
  2011. }
  2012. if (aout->main.kick == KICK_NOTE) {
  2013. aout->main.kick_flag = 1;
  2014. }
  2015. aout->main.kick=KICK_ABSENT;
  2016. tmpvol = aout->main.fadevol; /* max 32768 */
  2017. tmpvol *= aout->main.chanvol; /* * max 64 */
  2018. tmpvol *= aout->main.outvolume; /* * max 256 */
  2019. tmpvol /= (256 * 64); /* tmpvol is max 32768 again */
  2020. aout->totalvol = tmpvol >> 2; /* used to determine samplevolume */
  2021. tmpvol *= envvol; /* * max 256 */
  2022. tmpvol *= mod->volume; /* * max 128 */
  2023. tmpvol /= (128 * 256 * 128);
  2024. /* fade out */
  2025. if (mod->sngpos>=mod->numpos)
  2026. tmpvol=0;
  2027. else
  2028. tmpvol=(tmpvol*max_volume)/128;
  2029. if ((aout->masterchn!=-1)&& mod->control[aout->masterchn].muted)
  2030. Voice_SetVolume_internal(channel,0);
  2031. else {
  2032. Voice_SetVolume_internal(channel,tmpvol);
  2033. if ((tmpvol)&&(aout->master)&&(aout->master->slave==aout))
  2034. mod->realchn++;
  2035. mod->totalchn++;
  2036. }
  2037. if (aout->main.panning==PAN_SURROUND)
  2038. Voice_SetPanning_internal(channel,PAN_SURROUND);
  2039. else
  2040. if ((mod->panflag)&&(aout->penv.flg & EF_ON))
  2041. Voice_SetPanning_internal(channel,
  2042.     DoPan(envpan,aout->main.panning));
  2043. else
  2044. Voice_SetPanning_internal(channel,aout->main.panning);
  2045. if (aout->main.period && s->vibdepth)
  2046. switch (s->vibtype) {
  2047. case 0:
  2048. vibval=avibtab[s->avibpos&127];
  2049. if (aout->avibpos & 0x80) vibval=-vibval;
  2050. break;
  2051. case 1:
  2052. vibval=64;
  2053. if (aout->avibpos & 0x80) vibval=-vibval;
  2054. break;
  2055. case 2:
  2056. vibval=63-(((aout->avibpos+128)&255)>>1);
  2057. break;
  2058. default:
  2059. vibval=(((aout->avibpos+128)&255)>>1)-64;
  2060. break;
  2061. }
  2062. else
  2063. vibval=0;
  2064. if (s->vibflags & AV_IT) {
  2065. if ((aout->aswppos>>8)<s->vibdepth) {
  2066. aout->aswppos += s->vibsweep;
  2067. vibdpt=aout->aswppos;
  2068. } else
  2069. vibdpt=s->vibdepth<<8;
  2070. vibval=(vibval*vibdpt)>>16;
  2071. if (aout->mflag) {
  2072. if (!(mod->flags&UF_LINEAR)) vibval>>=1;
  2073. aout->main.period-=vibval;
  2074. }
  2075. } else {
  2076. /* do XM style auto-vibrato */
  2077. if (!(aout->main.keyoff & KEY_OFF)) {
  2078. if (aout->aswppos<s->vibsweep) {
  2079. vibdpt=(aout->aswppos*s->vibdepth)/s->vibsweep;
  2080. aout->aswppos++;
  2081. } else
  2082. vibdpt=s->vibdepth;
  2083. } else {
  2084. /* keyoff -> depth becomes 0 if final depth wasn't reached or
  2085.    stays at final level if depth WAS reached */
  2086. if (aout->aswppos>=s->vibsweep)
  2087. vibdpt=s->vibdepth;
  2088. else
  2089. vibdpt=0;
  2090. }
  2091. vibval=(vibval*vibdpt)>>8;
  2092. aout->main.period-=vibval;
  2093. }
  2094. /* update vibrato position */
  2095. aout->avibpos=(aout->avibpos+s->vibrate)&0xff;
  2096. /* process pitch envelope */
  2097. playperiod=aout->main.period;
  2098. if ((aout->main.pitflg&EF_ON)&&(envpit!=32)) {
  2099. long p1;
  2100. envpit-=32;
  2101. if ((aout->main.note<<1)+envpit<=0) envpit=-(aout->main.note<<1);
  2102. p1=GetPeriod(mod->flags, ((UWORD)aout->main.note<<1)+envpit,
  2103.     aout->master->speed)-aout->masterperiod;
  2104. if (p1>0) {
  2105. if ((UWORD)(playperiod+p1)<=playperiod) {
  2106. p1=0;
  2107. aout->main.keyoff|=KEY_OFF;
  2108. }
  2109. } else if (p1<0) {
  2110. if ((UWORD)(playperiod+p1)>=playperiod) {
  2111. p1=0;
  2112. aout->main.keyoff|=KEY_OFF;
  2113. }
  2114. }
  2115. playperiod+=p1;
  2116. }
  2117. if (!aout->main.fadevol) { /* check for a dead note (fadevol=0) */
  2118. Voice_Stop_internal(channel);
  2119. mod->totalchn--;
  2120. if ((tmpvol)&&(aout->master)&&(aout->master->slave==aout))
  2121. mod->realchn--;
  2122. } else {
  2123. Voice_SetFrequency_internal(channel,
  2124.                             getfrequency(mod->flags,playperiod));
  2125. /* if keyfade, start substracting fadeoutspeed from fadevol: */
  2126. if ((i)&&(aout->main.keyoff&KEY_FADE)) {
  2127. if (aout->main.fadevol>=i->volfade)
  2128. aout->main.fadevol-=i->volfade;
  2129. else
  2130. aout->main.fadevol=0;
  2131. }
  2132. }
  2133. md_bpm=mod->bpm+mod->relspd;
  2134. if (md_bpm<32)
  2135. md_bpm=32;
  2136. else if ((!(mod->flags&UF_HIGHBPM)) && md_bpm>255)
  2137. md_bpm=255;
  2138. }
  2139. }
  2140. /* Handles new notes or instruments */
  2141. void pt_Notes(MODULE *mod)
  2142. {
  2143. SWORD channel;
  2144. MP_CONTROL *a;
  2145. UBYTE c,inst;
  2146. int tr,funky; /* funky is set to indicate note or instrument change */
  2147. for (channel=0;channel<mod->numchn;channel++) {
  2148. a=&mod->control[channel];
  2149. if (mod->sngpos>=mod->numpos) {
  2150. tr=mod->numtrk;
  2151. mod->numrow=0;
  2152. } else {
  2153. tr=mod->patterns[(mod->positions[mod->sngpos]*mod->numchn)+channel];
  2154. mod->numrow=mod->pattrows[mod->positions[mod->sngpos]];
  2155. }
  2156. a->row=(tr<mod->numtrk)?UniFindRow(mod->tracks[tr],mod->patpos):NULL;
  2157. a->newsamp=0;
  2158. if (!mod->vbtick) a->main.notedelay=0;
  2159. if (!a->row) continue;
  2160. UniSetRow(a->row);
  2161. funky=0;
  2162. while((c=UniGetByte()))
  2163. switch (c) {
  2164. case UNI_NOTE:
  2165. funky|=1;
  2166. a->oldnote=a->anote,a->anote=UniGetByte();
  2167. a->main.kick =KICK_NOTE;
  2168. a->main.start=-1;
  2169. a->sliding=0;
  2170. /* retrig tremolo and vibrato waves ? */
  2171. if (!(a->wavecontrol & 0x80)) a->trmpos=0;
  2172. if (!(a->wavecontrol & 0x08)) a->vibpos=0;
  2173. if (!a->panbwave) a->panbpos=0;
  2174. break;
  2175. case UNI_INSTRUMENT:
  2176. inst=UniGetByte();
  2177. if (inst>=mod->numins) break; /* safety valve */
  2178. funky|=2;
  2179. a->main.i=(mod->flags & UF_INST)?&mod->instruments[inst]:NULL;
  2180. a->retrig=0;
  2181. a->s3mtremor=0;
  2182. a->ultoffset=0;
  2183. a->main.sample=inst;
  2184. break;
  2185. default:
  2186. UniSkipOpcode();
  2187. break;
  2188. }
  2189. if (funky) {
  2190. INSTRUMENT *i;
  2191. SAMPLE *s;
  2192. if ((i=a->main.i)) {
  2193. if (i->samplenumber[a->anote] >= mod->numsmp) continue;
  2194. s=&mod->samples[i->samplenumber[a->anote]];
  2195. a->main.note=i->samplenote[a->anote];
  2196. } else {
  2197. a->main.note=a->anote;
  2198. s=&mod->samples[a->main.sample];
  2199. }
  2200. if (a->main.s!=s) {
  2201. a->main.s=s;
  2202. a->newsamp=a->main.period;
  2203. }
  2204. /* channel or instrument determined panning ? */
  2205. a->main.panning=mod->panning[channel];
  2206. if (s->flags & SF_OWNPAN)
  2207. a->main.panning=s->panning;
  2208. else if ((i)&&(i->flags & IF_OWNPAN))
  2209. a->main.panning=i->panning;
  2210. a->main.handle=s->handle;
  2211. a->speed=s->speed;
  2212. if (i) {
  2213. if ((mod->panflag)&&(i->flags & IF_PITCHPAN)
  2214.    &&(a->main.panning!=PAN_SURROUND)){
  2215. a->main.panning+=
  2216.     ((a->anote-i->pitpancenter)*i->pitpansep)/8;
  2217. if (a->main.panning<PAN_LEFT)
  2218. a->main.panning=PAN_LEFT;
  2219. else if (a->main.panning>PAN_RIGHT)
  2220. a->main.panning=PAN_RIGHT;
  2221. }
  2222. a->main.pitflg=i->pitflg;
  2223. a->main.volflg=i->volflg;
  2224. a->main.panflg=i->panflg;
  2225. a->main.nna=i->nnatype;
  2226. a->dca=i->dca;
  2227. a->dct=i->dct;
  2228. } else {
  2229. a->main.pitflg=a->main.volflg=a->main.panflg=0;
  2230. a->main.nna=a->dca=0;
  2231. a->dct=DCT_OFF;
  2232. }
  2233. if (funky&2) /* instrument change */ {
  2234. /* IT random volume variations: 0:8 bit fixed, and one bit for
  2235.    sign. */
  2236. a->volume=a->tmpvolume=s->volume;
  2237. if ((s)&&(i)) {
  2238. if (i->rvolvar) {
  2239. a->volume=a->tmpvolume=s->volume+
  2240.   ((s->volume*((SLONG)i->rvolvar*(SLONG)getrandom(512)
  2241.   ))/25600);
  2242. if (a->volume<0)
  2243. a->volume=a->tmpvolume=0;
  2244. else if (a->volume>64)
  2245. a->volume=a->tmpvolume=64;
  2246. }
  2247. if ((mod->panflag)&&(a->main.panning!=PAN_SURROUND)) {
  2248. a->main.panning+=((a->main.panning*((SLONG)i->rpanvar*
  2249.   (SLONG)getrandom(512)))/25600);
  2250. if (a->main.panning<PAN_LEFT)
  2251. a->main.panning=PAN_LEFT;
  2252. else if (a->main.panning>PAN_RIGHT)
  2253. a->main.panning=PAN_RIGHT;
  2254. }
  2255. }
  2256. }
  2257. a->wantedperiod=a->tmpperiod=
  2258.     GetPeriod(mod->flags, (UWORD)a->main.note<<1,a->speed);
  2259. a->main.keyoff=KEY_KICK;
  2260. }
  2261. }
  2262. }
  2263. /* Handles effects */
  2264. void pt_EffectsPass1(MODULE *mod)
  2265. {
  2266. SWORD channel;
  2267. MP_CONTROL *a;
  2268. MP_VOICE *aout;
  2269. int explicitslides;
  2270. for (channel=0;channel<mod->numchn;channel++) {
  2271. a=&mod->control[channel];
  2272. if ((aout=a->slave)) {
  2273. a->main.fadevol=aout->main.fadevol;
  2274. a->main.period=aout->main.period;
  2275. if (a->main.kick==KICK_KEYOFF)
  2276. a->main.keyoff=aout->main.keyoff;
  2277. }
  2278. if (!a->row) continue;
  2279. UniSetRow(a->row);
  2280. a->ownper=a->ownvol=0;
  2281. explicitslides = pt_playeffects(mod, channel, a);
  2282. /* continue volume slide if necessary for XM and IT */
  2283. if (mod->flags&UF_BGSLIDES) {
  2284. if (!explicitslides && a->sliding)
  2285. DoS3MVolSlide(mod->vbtick, mod->flags, a, 0);
  2286. else if (a->tmpvolume)
  2287. a->sliding = explicitslides;
  2288. }
  2289. if (!a->ownper)
  2290. a->main.period=a->tmpperiod;
  2291. if (!a->ownvol)
  2292. a->volume=a->tmpvolume;
  2293. if (a->main.s) {
  2294. if (a->main.i)
  2295. a->main.outvolume=
  2296.     (a->volume*a->main.s->globvol*a->main.i->globvol)>>10;
  2297. else
  2298. a->main.outvolume=(a->volume*a->main.s->globvol)>>4;
  2299. if (a->main.outvolume>256)
  2300. a->main.outvolume=256;
  2301. else if (a->main.outvolume<0)
  2302. a->main.outvolume=0;
  2303. }
  2304. }
  2305. }
  2306. /* NNA management */
  2307. void pt_NNA(MODULE *mod)
  2308. {
  2309. SWORD channel;
  2310. MP_CONTROL *a;
  2311. for (channel=0;channel<mod->numchn;channel++) {
  2312. a=&mod->control[channel];
  2313. if (a->main.kick==KICK_NOTE) {
  2314. BOOL kill=0;
  2315. if (a->slave) {
  2316. MP_VOICE *aout;
  2317. aout=a->slave;
  2318. if (aout->main.nna & NNA_MASK) {
  2319. /* Make sure the old MP_VOICE channel knows it has no
  2320.    master now ! */
  2321. a->slave=NULL;
  2322. /* assume the channel is taken by NNA */
  2323. aout->mflag=0;
  2324. switch (aout->main.nna) {
  2325. case NNA_CONTINUE: /* continue note, do nothing */
  2326. break;
  2327. case NNA_OFF: /* note off */
  2328. aout->main.keyoff|=KEY_OFF;
  2329. if ((!(aout->main.volflg & EF_ON))||
  2330.   (aout->main.volflg & EF_LOOP))
  2331. aout->main.keyoff=KEY_KILL;
  2332. break;
  2333. case NNA_FADE:
  2334. aout->main.keyoff |= KEY_FADE;
  2335. break;
  2336. }
  2337. }
  2338. }
  2339. if (a->dct!=DCT_OFF) {
  2340. int t;
  2341. for (t=0;t<md_sngchn;t++)
  2342. if ((!Voice_Stopped_internal(t))&&
  2343.    (mod->voice[t].masterchn==channel)&&
  2344.    (a->main.sample==mod->voice[t].main.sample)) {
  2345. kill=0;
  2346. switch (a->dct) {
  2347. case DCT_NOTE:
  2348. if (a->main.note==mod->voice[t].main.note)
  2349. kill=1;
  2350. break;
  2351. case DCT_SAMPLE:
  2352. if (a->main.handle==mod->voice[t].main.handle)
  2353. kill=1;
  2354. break;
  2355. case DCT_INST:
  2356. kill=1;
  2357. break;
  2358. }
  2359. if (kill)
  2360. switch (a->dca) {
  2361. case DCA_CUT:
  2362. mod->voice[t].main.fadevol=0;
  2363. break;
  2364. case DCA_OFF:
  2365. mod->voice[t].main.keyoff|=KEY_OFF;
  2366. if ((!(mod->voice[t].main.volflg&EF_ON))||
  2367.     (mod->voice[t].main.volflg&EF_LOOP))
  2368. mod->voice[t].main.keyoff=KEY_KILL;
  2369. break;
  2370. case DCA_FADE:
  2371. mod->voice[t].main.keyoff|=KEY_FADE;
  2372. break;
  2373. }
  2374. }
  2375. }
  2376. } /* if (a->main.kick==KICK_NOTE) */
  2377. }
  2378. }
  2379. /* Setup module and NNA voices */
  2380. void pt_SetupVoices(MODULE *mod)
  2381. {
  2382. SWORD channel;
  2383. MP_CONTROL *a;
  2384. MP_VOICE *aout;
  2385. for (channel=0;channel<mod->numchn;channel++) {
  2386. a=&mod->control[channel];
  2387. if (a->main.notedelay) continue;
  2388. if (a->main.kick==KICK_NOTE) {
  2389. /* if no channel was cut above, find an empty or quiet channel
  2390.    here */
  2391. if (mod->flags&UF_NNA) {
  2392. if (!a->slave) {
  2393. int newchn;
  2394. if ((newchn=MP_FindEmptyChannel(mod))!=-1)
  2395. a->slave=&mod->voice[a->slavechn=newchn];
  2396. }
  2397. } else 
  2398. a->slave=&mod->voice[a->slavechn=channel];
  2399. /* assign parts of MP_VOICE only done for a KICK_NOTE */
  2400. if ((aout=a->slave)) {
  2401. if (aout->mflag && aout->master) aout->master->slave=NULL;
  2402. aout->master=a;
  2403. a->slave=aout;
  2404. aout->masterchn=channel;
  2405. aout->mflag=1;
  2406. }
  2407. } else
  2408. aout=a->slave;
  2409. if (aout)
  2410. aout->main=a->main;
  2411. a->main.kick=KICK_ABSENT;
  2412. }
  2413. }
  2414. /* second effect pass */
  2415. void pt_EffectsPass2(MODULE *mod)
  2416. {
  2417. SWORD channel;
  2418. MP_CONTROL *a;
  2419. UBYTE c;
  2420. for (channel=0;channel<mod->numchn;channel++) {
  2421. a=&mod->control[channel];
  2422. if (!a->row) continue;
  2423. UniSetRow(a->row);
  2424. while((c=UniGetByte()))
  2425. if (c==UNI_ITEFFECTS0) {
  2426. c=UniGetByte();
  2427. if ((c>>4)==SS_S7EFFECTS)
  2428. DoNNAEffects(mod, a, c&0xf);
  2429. } else
  2430. UniSkipOpcode();
  2431. }
  2432. }
  2433. void Player_HandleTick(void)
  2434. {
  2435. SWORD channel;
  2436. int max_volume;
  2437. #if 0
  2438. /* don't handle the very first ticks, this allows the other hardware to
  2439.    settle down so we don't loose any starting notes */
  2440. if (isfirst) {
  2441. isfirst--;
  2442. return;
  2443. }
  2444. #endif
  2445. if ((!pf)||(pf->forbid)||(pf->sngpos>=pf->numpos)) return;
  2446. /* update time counter (sngtime is in milliseconds (in fact 2^-10)) */
  2447. pf->sngremainder+=(1<<9)*5; /* thus 2.5*(1<<10), since fps=0.4xtempo */
  2448. pf->sngtime+=pf->sngremainder/pf->bpm;
  2449. pf->sngremainder%=pf->bpm;
  2450. if (++pf->vbtick>=pf->sngspd) {
  2451. if (pf->pat_repcrazy) 
  2452. pf->pat_repcrazy=0; /* play 2 times row 0 */
  2453. else
  2454. pf->patpos++;
  2455. pf->vbtick=0;
  2456. /* process pattern-delay. pf->patdly2 is the counter and pf->patdly is
  2457.    the command memory. */
  2458. if (pf->patdly)
  2459. pf->patdly2=pf->patdly,pf->patdly=0;
  2460. if (pf->patdly2) {
  2461. /* patterndelay active */
  2462. if (--pf->patdly2)
  2463. /* so turn back pf->patpos by 1 */
  2464. if (pf->patpos) pf->patpos--;
  2465. }
  2466. /* do we have to get a new patternpointer ? (when pf->patpos reaches the
  2467.    pattern size, or when a patternbreak is active) */
  2468. if (((pf->patpos>=pf->numrow)&&(pf->numrow>0))&&(!pf->posjmp))
  2469. pf->posjmp=3;
  2470. if (pf->posjmp) {
  2471. pf->patpos=pf->numrow?(pf->patbrk%pf->numrow):0;
  2472. pf->pat_repcrazy=0;
  2473. pf->sngpos+=(pf->posjmp-2);
  2474. for (channel=0;channel<pf->numchn;channel++)
  2475. pf->control[channel].pat_reppos=-1;
  2476. pf->patbrk=pf->posjmp=0;
  2477. /* handle the "---" (end of song) pattern since it can occur
  2478.    *inside* the module in some formats */
  2479. if ((pf->sngpos>=pf->numpos)||
  2480. (pf->positions[pf->sngpos]==LAST_PATTERN)) {
  2481. if (!pf->wrap) return;
  2482. if (!(pf->sngpos=pf->reppos)) {
  2483.     pf->volume=pf->initvolume>128?128:pf->initvolume;
  2484. if(pf->initspeed!=0)
  2485. pf->sngspd=pf->initspeed<32?pf->initspeed:32;
  2486. else
  2487. pf->sngspd=6;
  2488. pf->bpm=pf->inittempo<32?32:pf->inittempo;
  2489. }
  2490. }
  2491. if (pf->sngpos<0) pf->sngpos=pf->numpos-1;
  2492. }
  2493. if (!pf->patdly2)
  2494. pt_Notes(pf);
  2495. }
  2496. /* Fade global volume if enabled and we're playing the last pattern */
  2497. if (((pf->sngpos==pf->numpos-1)||
  2498.  (pf->positions[pf->sngpos+1]==LAST_PATTERN))&&
  2499.     (pf->fadeout))
  2500. max_volume=pf->numrow?((pf->numrow-pf->patpos)*128)/pf->numrow:0;
  2501. else
  2502. max_volume=128;
  2503. pt_EffectsPass1(pf);
  2504. if (pf->flags&UF_NNA)
  2505. pt_NNA(pf);
  2506. pt_SetupVoices(pf);
  2507. pt_EffectsPass2(pf);
  2508. /* now set up the actual hardware channel playback information */
  2509. pt_UpdateVoices(pf, max_volume);
  2510. }
  2511. static void Player_Init_internal(MODULE* mod)
  2512. {
  2513. int t;
  2514. for (t=0;t<mod->numchn;t++) {
  2515. mod->control[t].main.chanvol=mod->chanvol[t];
  2516. mod->control[t].main.panning=mod->panning[t];
  2517. }
  2518. mod->sngtime=0;
  2519. mod->sngremainder=0;
  2520. mod->pat_repcrazy=0;
  2521. mod->sngpos=0;
  2522. if(mod->initspeed!=0)
  2523. mod->sngspd=mod->initspeed<32?mod->initspeed:32;
  2524. else
  2525. mod->sngspd=6;
  2526. mod->volume=mod->initvolume>128?128:mod->initvolume;
  2527. mod->vbtick=mod->sngspd;
  2528. mod->patdly=0;
  2529. mod->patdly2=0;
  2530. mod->bpm=mod->inittempo<32?32:mod->inittempo;
  2531. mod->realchn=0;
  2532. mod->patpos=0;
  2533. mod->posjmp=2; /* make sure the player fetches the first note */
  2534. mod->numrow=-1;
  2535. mod->patbrk=0;
  2536. }
  2537. BOOL Player_Init(MODULE* mod)
  2538. {
  2539. mod->extspd=1;
  2540. mod->panflag=1;
  2541. mod->wrap=0;
  2542. mod->loop=1;
  2543. mod->fadeout=0;
  2544. mod->relspd=0;
  2545. /* make sure the player doesn't start with garbage */
  2546. if (!(mod->control=(MP_CONTROL*)_mm_calloc(mod->numchn,sizeof(MP_CONTROL))))
  2547. return 1;
  2548. if (!(mod->voice=(MP_VOICE*)_mm_calloc(md_sngchn,sizeof(MP_VOICE))))
  2549. return 1;
  2550. Player_Init_internal(mod);
  2551. return 0;
  2552. }
  2553. void Player_Exit_internal(MODULE* mod)
  2554. {
  2555. if (!mod)
  2556. return;
  2557. /* Stop playback if necessary */
  2558. if (mod==pf) {
  2559. Player_Stop_internal();
  2560. pf=NULL;
  2561. }
  2562. if (mod->control)
  2563. free(mod->control);
  2564. if (mod->voice)
  2565. free(mod->voice);
  2566. mod->control=NULL;
  2567. mod->voice=NULL;
  2568. }
  2569. void Player_Exit(MODULE* mod)
  2570. {
  2571. MUTEX_LOCK(vars);
  2572. Player_Exit_internal(mod);
  2573. MUTEX_UNLOCK(vars);
  2574. }
  2575. MIKMODAPI void Player_SetVolume(SWORD volume)
  2576. {
  2577. MUTEX_LOCK(vars);
  2578. if (pf)
  2579. pf->volume=(volume<0)?0:(volume>128)?128:volume;
  2580. MUTEX_UNLOCK(vars);
  2581. }
  2582. MIKMODAPI MODULE* Player_GetModule(void)
  2583. {
  2584. MODULE* result;
  2585. MUTEX_LOCK(vars);
  2586. result=pf;
  2587. MUTEX_UNLOCK(vars);
  2588. return result;
  2589. }
  2590. MIKMODAPI void Player_Start(MODULE *mod)
  2591. {
  2592. int t;
  2593. if (!mod)
  2594. return;
  2595. if (!MikMod_Active())
  2596. MikMod_EnableOutput();
  2597. mod->forbid=0;
  2598. MUTEX_LOCK(vars);
  2599. if (pf!=mod) {
  2600. /* new song is being started, so completely stop out the old one. */
  2601. if (pf) pf->forbid=1;
  2602. for (t=0;t<md_sngchn;t++) Voice_Stop_internal(t);
  2603. }
  2604. pf=mod;
  2605. MUTEX_UNLOCK(vars);
  2606. }
  2607. void Player_Stop_internal(void)
  2608. {
  2609. if (!md_sfxchn) MikMod_DisableOutput_internal();
  2610. if (pf) pf->forbid=1;
  2611. pf=NULL;
  2612. }
  2613. MIKMODAPI void Player_Stop(void)
  2614. {
  2615. MUTEX_LOCK(vars);
  2616. Player_Stop_internal();
  2617. MUTEX_UNLOCK(vars);
  2618. }
  2619. MIKMODAPI BOOL Player_Active(void)
  2620. {
  2621. BOOL result=0;
  2622. MUTEX_LOCK(vars);
  2623. if (pf)
  2624. result=(!(pf->sngpos>=pf->numpos));
  2625. MUTEX_UNLOCK(vars);
  2626. return result;
  2627. }
  2628. MIKMODAPI void Player_NextPosition(void)
  2629. {
  2630. MUTEX_LOCK(vars);
  2631. if (pf) {
  2632. int t;
  2633. pf->forbid=1;
  2634. pf->posjmp=3;
  2635. pf->patbrk=0;
  2636. pf->vbtick=pf->sngspd;
  2637. for (t=0;t<md_sngchn;t++) {
  2638. Voice_Stop_internal(t);
  2639. pf->voice[t].main.i=NULL;
  2640. pf->voice[t].main.s=NULL;
  2641. }
  2642. for (t=0;t<pf->numchn;t++) {
  2643. pf->control[t].main.i=NULL;
  2644. pf->control[t].main.s=NULL;
  2645. }
  2646. pf->forbid=0;
  2647. }
  2648. MUTEX_UNLOCK(vars);
  2649. }
  2650. MIKMODAPI void Player_PrevPosition(void)
  2651. {
  2652. MUTEX_LOCK(vars);
  2653. if (pf) {
  2654. int t;
  2655. pf->forbid=1;
  2656. pf->posjmp=1;
  2657. pf->patbrk=0;
  2658. pf->vbtick=pf->sngspd;
  2659. for (t=0;t<md_sngchn;t++) {
  2660. Voice_Stop_internal(t);
  2661. pf->voice[t].main.i=NULL;
  2662. pf->voice[t].main.s=NULL;
  2663. }
  2664. for (t=0;t<pf->numchn;t++) {
  2665. pf->control[t].main.i=NULL;
  2666. pf->control[t].main.s=NULL;
  2667. }
  2668. pf->forbid=0;
  2669. }
  2670. MUTEX_UNLOCK(vars);
  2671. }
  2672. MIKMODAPI void Player_SetPosition(UWORD pos)
  2673. {
  2674. MUTEX_LOCK(vars);
  2675. if (pf) {
  2676. int t;
  2677. pf->forbid=1;
  2678. if (pos>=pf->numpos) pos=pf->numpos;
  2679. pf->posjmp=2;
  2680. pf->patbrk=0;
  2681. pf->sngpos=pos;
  2682. pf->vbtick=pf->sngspd;
  2683. for (t=0;t<md_sngchn;t++) {
  2684. Voice_Stop_internal(t);
  2685. pf->voice[t].main.i=NULL;
  2686. pf->voice[t].main.s=NULL;
  2687. }
  2688. for (t=0;t<pf->numchn;t++) {
  2689. pf->control[t].main.i=NULL;
  2690. pf->control[t].main.s=NULL;
  2691. }
  2692. pf->forbid=0;
  2693. if (!pos)
  2694. Player_Init_internal(pf);
  2695. }
  2696. MUTEX_UNLOCK(vars);
  2697. }    
  2698. static void Player_Unmute_internal(SLONG arg1,va_list ap)
  2699. {
  2700. SLONG t,arg2,arg3=0;
  2701. if (pf) {
  2702. switch (arg1) {
  2703. case MUTE_INCLUSIVE:
  2704. if (((!(arg2=va_arg(ap,SLONG)))&&(!(arg3=va_arg(ap,SLONG))))||
  2705.    (arg2>arg3)||(arg3>=pf->numchn))
  2706. return;
  2707. for (;arg2<pf->numchn && arg2<=arg3;arg2++)
  2708. pf->control[arg2].muted=0;
  2709. break;
  2710. case MUTE_EXCLUSIVE:
  2711. if (((!(arg2=va_arg(ap,SLONG)))&&(!(arg3=va_arg(ap,SLONG))))||
  2712.    (arg2>arg3)||(arg3>=pf->numchn))
  2713. return;
  2714. for (t=0;t<pf->numchn;t++) {
  2715. if ((t>=arg2) && (t<=arg3))
  2716. continue;
  2717. pf->control[t].muted=0;
  2718. }
  2719. break;
  2720. default:
  2721. if (arg1<pf->numchn) pf->control[arg1].muted=0;
  2722. break;
  2723. }
  2724. }
  2725. }
  2726. MIKMODAPI void Player_Unmute(SLONG arg1, ...)
  2727. {
  2728. va_list args;
  2729. va_start(args,arg1);
  2730. MUTEX_LOCK(vars);
  2731. Player_Unmute_internal(arg1,args);
  2732. MUTEX_UNLOCK(vars);
  2733. va_end(args);
  2734. }
  2735. static void Player_Mute_internal(SLONG arg1,va_list ap)
  2736. {
  2737. SLONG t,arg2,arg3=0;
  2738. if (pf) {
  2739. switch (arg1) {
  2740. case MUTE_INCLUSIVE:
  2741. if (((!(arg2=va_arg(ap,SLONG)))&&(!(arg3=va_arg(ap,SLONG))))||
  2742.     (arg2>arg3)||(arg3>=pf->numchn))
  2743. return;
  2744. for (;arg2<pf->numchn && arg2<=arg3;arg2++)
  2745. pf->control[arg2].muted=1;
  2746. break;
  2747. case MUTE_EXCLUSIVE:
  2748. if (((!(arg2=va_arg(ap,SLONG)))&&(!(arg3=va_arg(ap,SLONG))))||
  2749.     (arg2>arg3)||(arg3>=pf->numchn))
  2750. return;
  2751. for (t=0;t<pf->numchn;t++) {
  2752. if ((t>=arg2) && (t<=arg3))
  2753. continue;
  2754. pf->control[t].muted=1;
  2755. }
  2756. break;
  2757. default:
  2758. if (arg1<pf->numchn)
  2759. pf->control[arg1].muted=1;
  2760. break;
  2761. }
  2762. }
  2763. }
  2764. MIKMODAPI void Player_Mute(SLONG arg1,...)
  2765. {
  2766. va_list args;
  2767. va_start(args,arg1);
  2768. MUTEX_LOCK(vars);
  2769. Player_Mute_internal(arg1,args);
  2770. MUTEX_UNLOCK(vars);
  2771. va_end(args);
  2772. }
  2773. static void Player_ToggleMute_internal(SLONG arg1,va_list ap)
  2774. {
  2775. SLONG arg2,arg3=0;
  2776. ULONG t;
  2777. if (pf) {
  2778. switch (arg1) {
  2779. case MUTE_INCLUSIVE:
  2780. if (((!(arg2=va_arg(ap,SLONG)))&&(!(arg3=va_arg(ap,SLONG))))||
  2781.     (arg2>arg3)||(arg3>=pf->numchn))
  2782. return;
  2783. for (;arg2<pf->numchn && arg2<=arg3;arg2++)
  2784. pf->control[arg2].muted=1-pf->control[arg2].muted;
  2785. break;
  2786. case MUTE_EXCLUSIVE:
  2787. if (((!(arg2=va_arg(ap,SLONG)))&&(!(arg3=va_arg(ap,SLONG))))||
  2788.     (arg2>arg3)||(arg3>=pf->numchn))
  2789. return;
  2790. for (t=0;t<pf->numchn;t++) {
  2791. if ((t>=arg2) && (t<=arg3))
  2792. continue;
  2793. pf->control[t].muted=1-pf->control[t].muted;
  2794. }
  2795. break;
  2796. default:
  2797. if (arg1<pf->numchn) 
  2798. pf->control[arg1].muted=1-pf->control[arg1].muted;
  2799. break;
  2800. }
  2801. }
  2802. }
  2803. MIKMODAPI void Player_ToggleMute(SLONG arg1,...)
  2804. {
  2805. va_list args;
  2806. va_start(args,arg1);
  2807. MUTEX_LOCK(vars);
  2808. Player_ToggleMute_internal(arg1,args);
  2809. MUTEX_UNLOCK(vars);
  2810. va_end(args);
  2811. }
  2812. MIKMODAPI BOOL Player_Muted(UBYTE chan)
  2813. {
  2814. BOOL result=1;
  2815. MUTEX_LOCK(vars);
  2816. if (pf)
  2817. result=(chan<pf->numchn)?pf->control[chan].muted:1;
  2818. MUTEX_UNLOCK(vars);
  2819. return result;
  2820. }
  2821. MIKMODAPI int Player_GetChannelVoice(UBYTE chan)
  2822. {
  2823. int result=0;
  2824. MUTEX_LOCK(vars);
  2825. if (pf)
  2826. result=(chan<pf->numchn)?pf->control[chan].slavechn:-1;
  2827. MUTEX_UNLOCK(vars);
  2828. return result;
  2829. }
  2830. MIKMODAPI UWORD Player_GetChannelPeriod(UBYTE chan)
  2831. {
  2832. UWORD result=0;
  2833. MUTEX_LOCK(vars);
  2834.     if (pf)
  2835.     result=(chan<pf->numchn)?pf->control[chan].main.period:0;
  2836. MUTEX_UNLOCK(vars);
  2837. return result;
  2838. }
  2839. BOOL Player_Paused_internal(void)
  2840. {
  2841. return pf?pf->forbid:1;
  2842. }
  2843. MIKMODAPI BOOL Player_Paused(void)
  2844. {
  2845. BOOL result;
  2846. MUTEX_LOCK(vars);
  2847. result=Player_Paused_internal();
  2848. MUTEX_UNLOCK(vars);
  2849. return result;
  2850. }
  2851. MIKMODAPI void Player_TogglePause(void)
  2852. {
  2853. MUTEX_LOCK(vars);
  2854. if (pf)
  2855. pf->forbid=1-pf->forbid;
  2856. MUTEX_UNLOCK(vars);
  2857. }
  2858. MIKMODAPI void Player_SetSpeed(UWORD speed)
  2859. {
  2860. MUTEX_LOCK(vars);
  2861. if (pf) 
  2862. pf->sngspd=speed?(speed<32?speed:32):1;
  2863. MUTEX_UNLOCK(vars);
  2864. }
  2865. MIKMODAPI void Player_SetTempo(UWORD tempo)
  2866. {
  2867. if (tempo<32) tempo=32;
  2868. MUTEX_LOCK(vars);
  2869. if (pf) {
  2870. if ((!(pf->flags&UF_HIGHBPM))&&(tempo>255)) tempo=255;
  2871. pf->bpm=tempo;
  2872. }
  2873. MUTEX_UNLOCK(vars);
  2874. }
  2875. MIKMODAPI int Player_QueryVoices(UWORD numvoices, VOICEINFO *vinfo)
  2876. {
  2877. int i;
  2878. if (numvoices > md_sngchn)
  2879. numvoices = md_sngchn;
  2880. MUTEX_LOCK(vars);
  2881. if (pf)
  2882. for (i = 0; i < md_sngchn; i++) {
  2883. vinfo [i].i = pf->voice[i].main.i;
  2884. vinfo [i].s = pf->voice[i].main.s;
  2885. vinfo [i].panning = pf->voice [i].main.panning;
  2886. vinfo [i].volume = pf->voice [i].main.chanvol;
  2887. vinfo [i].period = pf->voice [i].main.period;
  2888. vinfo [i].kick = pf->voice [i].main.kick_flag;
  2889. pf->voice [i].main.kick_flag = 0;
  2890. }
  2891. MUTEX_UNLOCK(vars);
  2892. return numvoices;
  2893. }
  2894. /* ex:set ts=4: */