home *** CD-ROM | disk | FTP | other *** search
/ PC Online 1999 February / PCO_0299.ISO / filesbbs / linux / mikmod-3.000 / mikmod-3 / mikmod-3.1.2 / playercode / mplayer.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-12-07  |  62.6 KB  |  2,630 lines

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