xref: /btstack/3rd-party/hxcmod-player/hxcmod.c (revision 4aa7d471d326f94fa7e80af8b1ccb77ec47dde0c)
1a4cd9b30SMilanka Ringwald ///////////////////////////////////////////////////////////////////////////////////
2a4cd9b30SMilanka Ringwald //-------------------------------------------------------------------------------//
3a4cd9b30SMilanka Ringwald //-------------------------------------------------------------------------------//
4a4cd9b30SMilanka Ringwald //-----------H----H--X----X-----CCCCC----22222----0000-----0000------11----------//
5a4cd9b30SMilanka Ringwald //----------H----H----X-X-----C--------------2---0----0---0----0--1--1-----------//
6a4cd9b30SMilanka Ringwald //---------HHHHHH-----X------C----------22222---0----0---0----0-----1------------//
7a4cd9b30SMilanka Ringwald //--------H----H----X--X----C----------2-------0----0---0----0-----1-------------//
8a4cd9b30SMilanka Ringwald //-------H----H---X-----X---CCCCC-----222222----0000-----0000----1111------------//
9a4cd9b30SMilanka Ringwald //-------------------------------------------------------------------------------//
10a4cd9b30SMilanka Ringwald //----------------------------------------------------- http://hxc2001.free.fr --//
11a4cd9b30SMilanka Ringwald ///////////////////////////////////////////////////////////////////////////////////
12a4cd9b30SMilanka Ringwald // File : hxcmod.c
13a4cd9b30SMilanka Ringwald // Contains: a tiny mod player
14a4cd9b30SMilanka Ringwald //
15d38efbbaSMatthias Ringwald // Written by: Jean Francois DEL NERO
16a4cd9b30SMilanka Ringwald //
17a4cd9b30SMilanka Ringwald // You are free to do what you want with this code.
18a4cd9b30SMilanka Ringwald // A credit is always appreciated if you include it into your prod :)
19a4cd9b30SMilanka Ringwald //
20a4cd9b30SMilanka Ringwald // This file include some parts of the Noisetracker/Soundtracker/Protracker
21a4cd9b30SMilanka Ringwald // Module Format documentation written by Andrew Scott (Adrenalin Software)
22a4cd9b30SMilanka Ringwald // (modformat.txt)
23a4cd9b30SMilanka Ringwald //
24a4cd9b30SMilanka Ringwald // The core (hxcmod.c/hxcmod.h) is designed to have the least external dependency.
25a4cd9b30SMilanka Ringwald // So it should be usable on almost all OS and systems.
26a4cd9b30SMilanka Ringwald // Please also note that no dynamic allocation is done into the HxCMOD core.
27a4cd9b30SMilanka Ringwald //
28a4cd9b30SMilanka Ringwald // Change History (most recent first):
29a4cd9b30SMilanka Ringwald ///////////////////////////////////////////////////////////////////////////////////
30a4cd9b30SMilanka Ringwald // HxCMOD Core API:
31a4cd9b30SMilanka Ringwald // -------------------------------------------
32a4cd9b30SMilanka Ringwald // int  hxcmod_init(modcontext * modctx)
33a4cd9b30SMilanka Ringwald //
34a4cd9b30SMilanka Ringwald // - Initialize the modcontext buffer. Must be called before doing anything else.
35a4cd9b30SMilanka Ringwald //   Return 1 if success. 0 in case of error.
36a4cd9b30SMilanka Ringwald // -------------------------------------------
37a4cd9b30SMilanka Ringwald // int  hxcmod_load( modcontext * modctx, void * mod_data, int mod_data_size )
38a4cd9b30SMilanka Ringwald //
39a4cd9b30SMilanka Ringwald // - "Load" a MOD from memory (from "mod_data" with size "mod_data_size").
40a4cd9b30SMilanka Ringwald //   Return 1 if success. 0 in case of error.
41a4cd9b30SMilanka Ringwald // -------------------------------------------
428201da88SMatthias Ringwald // void hxcmod_fillbuffer( modcontext * modctx, unsigned short * outbuffer, mssize nbsample, tracker_buffer_state * trkbuf )
43a4cd9b30SMilanka Ringwald //
44a4cd9b30SMilanka Ringwald // - Generate and return the next samples chunk to outbuffer.
45a4cd9b30SMilanka Ringwald //   nbsample specify the number of stereo 16bits samples you want.
46a4cd9b30SMilanka Ringwald //   The output format is signed 44100Hz 16-bit Stereo PCM samples.
47a4cd9b30SMilanka Ringwald //   The output buffer size in byte must be equal to ( nbsample * 2 * 2 ).
48a4cd9b30SMilanka Ringwald //   The optional trkbuf parameter can be used to get detailed status of the player. Put NULL/0 is unused.
49a4cd9b30SMilanka Ringwald // -------------------------------------------
50a4cd9b30SMilanka Ringwald // void hxcmod_unload( modcontext * modctx )
51a4cd9b30SMilanka Ringwald // - "Unload" / clear the player status.
52a4cd9b30SMilanka Ringwald // -------------------------------------------
53a4cd9b30SMilanka Ringwald ///////////////////////////////////////////////////////////////////////////////////
54a4cd9b30SMilanka Ringwald 
55a4cd9b30SMilanka Ringwald #include "hxcmod.h"
56a4cd9b30SMilanka Ringwald 
578201da88SMatthias Ringwald // BK4BSTACK_CHANGE START
588201da88SMatthias Ringwald 
598201da88SMatthias Ringwald // MODs ar either in ROM (MCUs) or in .text segment
608201da88SMatthias Ringwald #define HXCMOD_MOD_FILE_IN_ROM
618201da88SMatthias Ringwald 
628201da88SMatthias Ringwald #ifdef __GNUC__
638201da88SMatthias Ringwald #ifndef	__clang__
648201da88SMatthias Ringwald #pragma GCC diagnostic push
658201da88SMatthias Ringwald // -Wstringop-overflow unknown to Clang 16.0.0
668201da88SMatthias Ringwald #pragma GCC diagnostic ignored "-Wstringop-overflow"
678201da88SMatthias Ringwald #endif
688201da88SMatthias Ringwald #endif
698201da88SMatthias Ringwald 
708201da88SMatthias Ringwald // BK4BSTACK_CHANGE END
718201da88SMatthias Ringwald 
72a4cd9b30SMilanka Ringwald ///////////////////////////////////////////////////////////////////////////////////
73a4cd9b30SMilanka Ringwald 
74a4cd9b30SMilanka Ringwald // Effects list
75a4cd9b30SMilanka Ringwald #define EFFECT_ARPEGGIO              0x0 // Supported
76a4cd9b30SMilanka Ringwald #define EFFECT_PORTAMENTO_UP         0x1 // Supported
77a4cd9b30SMilanka Ringwald #define EFFECT_PORTAMENTO_DOWN       0x2 // Supported
78a4cd9b30SMilanka Ringwald #define EFFECT_TONE_PORTAMENTO       0x3 // Supported
79a4cd9b30SMilanka Ringwald #define EFFECT_VIBRATO               0x4 // Supported
80a4cd9b30SMilanka Ringwald #define EFFECT_VOLSLIDE_TONEPORTA    0x5 // Supported
81a4cd9b30SMilanka Ringwald #define EFFECT_VOLSLIDE_VIBRATO      0x6 // Supported
82a4cd9b30SMilanka Ringwald #define EFFECT_VOLSLIDE_TREMOLO      0x7 // - TO BE DONE -
83a4cd9b30SMilanka Ringwald #define EFFECT_SET_PANNING           0x8 // - TO BE DONE -
84a4cd9b30SMilanka Ringwald #define EFFECT_SET_OFFSET            0x9 // Supported
85a4cd9b30SMilanka Ringwald #define EFFECT_VOLUME_SLIDE          0xA // Supported
86a4cd9b30SMilanka Ringwald #define EFFECT_JUMP_POSITION         0xB // Supported
87a4cd9b30SMilanka Ringwald #define EFFECT_SET_VOLUME            0xC // Supported
88a4cd9b30SMilanka Ringwald #define EFFECT_PATTERN_BREAK         0xD // Supported
89a4cd9b30SMilanka Ringwald 
90a4cd9b30SMilanka Ringwald #define EFFECT_EXTENDED              0xE
91a4cd9b30SMilanka Ringwald #define EFFECT_E_FINE_PORTA_UP       0x1 // Supported
92a4cd9b30SMilanka Ringwald #define EFFECT_E_FINE_PORTA_DOWN     0x2 // Supported
93a4cd9b30SMilanka Ringwald #define EFFECT_E_GLISSANDO_CTRL      0x3 // - TO BE DONE -
94a4cd9b30SMilanka Ringwald #define EFFECT_E_VIBRATO_WAVEFORM    0x4 // - TO BE DONE -
958201da88SMatthias Ringwald #define EFFECT_E_SET_FINETUNE        0x5 // Supported
96a4cd9b30SMilanka Ringwald #define EFFECT_E_PATTERN_LOOP        0x6 // Supported
97a4cd9b30SMilanka Ringwald #define EFFECT_E_TREMOLO_WAVEFORM    0x7 // - TO BE DONE -
98a4cd9b30SMilanka Ringwald #define EFFECT_E_SET_PANNING_2       0x8 // - TO BE DONE -
998201da88SMatthias Ringwald #define EFFECT_E_RETRIGGER_NOTE      0x9 // Supported
100a4cd9b30SMilanka Ringwald #define EFFECT_E_FINE_VOLSLIDE_UP    0xA // Supported
101a4cd9b30SMilanka Ringwald #define EFFECT_E_FINE_VOLSLIDE_DOWN  0xB // Supported
102a4cd9b30SMilanka Ringwald #define EFFECT_E_NOTE_CUT            0xC // Supported
1038201da88SMatthias Ringwald #define EFFECT_E_NOTE_DELAY          0xD // Supported
104a4cd9b30SMilanka Ringwald #define EFFECT_E_PATTERN_DELAY       0xE // Supported
1058201da88SMatthias Ringwald #define EFFECT_E_INVERT_LOOP         0xF // Supported (W.I.P)
106a4cd9b30SMilanka Ringwald #define EFFECT_SET_SPEED             0xF0 // Supported
107a4cd9b30SMilanka Ringwald #define EFFECT_SET_TEMPO             0xF2 // Supported
108a4cd9b30SMilanka Ringwald 
109a4cd9b30SMilanka Ringwald #define PERIOD_TABLE_LENGTH  MAXNOTES
110a4cd9b30SMilanka Ringwald 
1118201da88SMatthias Ringwald 
1128201da88SMatthias Ringwald //
1138201da88SMatthias Ringwald // Finetuning periods -> Amiga period * 2^(-finetune/12/8)
1148201da88SMatthias Ringwald //
115b0920f25SMilanka Ringwald 
116a4cd9b30SMilanka Ringwald static const short periodtable[]=
117a4cd9b30SMilanka Ringwald {
1188201da88SMatthias Ringwald 	// Finetune 0 (* 1.000000), Offset 0x0000
119a4cd9b30SMilanka Ringwald 	27392, 25856, 24384, 23040, 21696, 20480, 19328, 18240, 17216, 16256, 15360, 14496,
120a4cd9b30SMilanka Ringwald 	13696, 12928, 12192, 11520, 10848, 10240,  9664,  9120,  8606,  8128,  7680,  7248,
121a4cd9b30SMilanka Ringwald 	 6848,  6464,  6096,  5760,  5424,  5120,  4832,  4560,  4304,  4064,  3840,  3624,
122a4cd9b30SMilanka Ringwald 	 3424,  3232,  3048,  2880,  2712,  2560,  2416,  2280,  2152,  2032,  1920,  1812,
123a4cd9b30SMilanka Ringwald 	 1712,  1616,  1524,  1440,  1356,  1280,  1208,  1140,  1076,  1016,   960,   906,
124a4cd9b30SMilanka Ringwald 	  856,   808,   762,   720,   678,   640,   604,   570,   538,   508,   480,   453,
125a4cd9b30SMilanka Ringwald 	  428,   404,   381,   360,   339,   320,   302,   285,   269,   254,   240,   226,
126a4cd9b30SMilanka Ringwald 	  214,   202,   190,   180,   170,   160,   151,   143,   135,   127,   120,   113,
127a4cd9b30SMilanka Ringwald 	  107,   101,    95,    90,    85,    80,    75,    71,    67,    63,    60,    56,
128a4cd9b30SMilanka Ringwald 	   53,    50,    47,    45,    42,    40,    37,    35,    33,    31,    30,    28,
129a4cd9b30SMilanka Ringwald 	   27,    25,    24,    22,    21,    20,    19,    18,    17,    16,    15,    14,
1308201da88SMatthias Ringwald 	   13,    13,    12,    11,    11,    10,     9,     9,     8,     8,     7,     7,
1318201da88SMatthias Ringwald 
1328201da88SMatthias Ringwald 	// Finetune 1 (* 0.992806), Offset 0x0120
1338201da88SMatthias Ringwald 	27195, 25670, 24209, 22874, 21540, 20333, 19189, 18109, 17092, 16139, 15249, 14392,
1348201da88SMatthias Ringwald 	13597, 12835, 12104, 11437, 10770, 10166,  9594,  9054,  8544,  8070,  7625,  7196,
1358201da88SMatthias Ringwald 	 6799,  6417,  6052,  5719,  5385,  5083,  4797,  4527,  4273,  4035,  3812,  3598,
1368201da88SMatthias Ringwald 	 3399,  3209,  3026,  2859,  2692,  2542,  2399,  2264,  2137,  2017,  1906,  1799,
1378201da88SMatthias Ringwald 	 1700,  1604,  1513,  1430,  1346,  1271,  1199,  1132,  1068,  1009,   953,   899,
1388201da88SMatthias Ringwald 	  850,   802,   757,   715,   673,   635,   600,   566,   534,   504,   477,   450,
1398201da88SMatthias Ringwald 	  425,   401,   378,   357,   337,   318,   300,   283,   267,   252,   238,   224,
1408201da88SMatthias Ringwald 	  212,   201,   189,   179,   169,   159,   150,   142,   134,   126,   119,   112,
1418201da88SMatthias Ringwald 	  106,   100,    94,    89,    84,    79,    74,    70,    67,    63,    60,    56,
1428201da88SMatthias Ringwald 	   53,    50,    47,    45,    42,    40,    37,    35,    33,    31,    30,    28,
1438201da88SMatthias Ringwald 	   27,    25,    24,    22,    21,    20,    19,    18,    17,    16,    15,    14,
1448201da88SMatthias Ringwald 	   13,    13,    12,    11,    11,    10,     9,     9,     8,     8,     7,     7,
1458201da88SMatthias Ringwald 
1468201da88SMatthias Ringwald 	// Finetune 2 (* 0.985663), Offset 0x0240
1478201da88SMatthias Ringwald 	26999, 25485, 24034, 22710, 21385, 20186, 19051, 17978, 16969, 16023, 15140, 14288,
1488201da88SMatthias Ringwald 	13500, 12743, 12017, 11355, 10692, 10093,  9525,  8989,  8483,  8011,  7570,  7144,
1498201da88SMatthias Ringwald 	 6750,  6371,  6009,  5677,  5346,  5047,  4763,  4495,  4242,  4006,  3785,  3572,
1508201da88SMatthias Ringwald 	 3375,  3186,  3004,  2839,  2673,  2523,  2381,  2247,  2121,  2003,  1892,  1786,
1518201da88SMatthias Ringwald 	 1687,  1593,  1502,  1419,  1337,  1262,  1191,  1124,  1061,  1001,   946,   893,
1528201da88SMatthias Ringwald 	  844,   796,   751,   710,   668,   631,   595,   562,   530,   501,   473,   447,
1538201da88SMatthias Ringwald 	  422,   398,   376,   355,   334,   315,   298,   281,   265,   250,   237,   223,
1548201da88SMatthias Ringwald 	  211,   199,   187,   177,   168,   158,   149,   141,   133,   125,   118,   111,
1558201da88SMatthias Ringwald 	  105,   100,    94,    89,    84,    79,    74,    70,    66,    62,    59,    55,
1568201da88SMatthias Ringwald 	   52,    49,    46,    44,    41,    39,    36,    34,    33,    31,    30,    28,
1578201da88SMatthias Ringwald 	   27,    25,    24,    22,    21,    20,    19,    18,    17,    16,    15,    14,
1588201da88SMatthias Ringwald 	   13,    13,    12,    11,    11,    10,     9,     9,     8,     8,     7,     7,
1598201da88SMatthias Ringwald 
1608201da88SMatthias Ringwald 	// Finetune 3 (* 0.978572), Offset 0x0360
1618201da88SMatthias Ringwald 	26805, 25302, 23862, 22546, 21231, 20041, 18914, 17849, 16847, 15908, 15031, 14185,
1628201da88SMatthias Ringwald 	13403, 12651, 11931, 11273, 10616, 10021,  9457,  8925,  8422,  7954,  7515,  7093,
1638201da88SMatthias Ringwald 	 6701,  6325,  5965,  5637,  5308,  5010,  4728,  4462,  4212,  3977,  3758,  3546,
1648201da88SMatthias Ringwald 	 3351,  3163,  2983,  2818,  2654,  2505,  2364,  2231,  2106,  1988,  1879,  1773,
1658201da88SMatthias Ringwald 	 1675,  1581,  1491,  1409,  1327,  1253,  1182,  1116,  1053,   994,   939,   887,
1668201da88SMatthias Ringwald 	  838,   791,   746,   705,   663,   626,   591,   558,   526,   497,   470,   443,
1678201da88SMatthias Ringwald 	  419,   395,   373,   352,   332,   313,   296,   279,   263,   249,   235,   221,
1688201da88SMatthias Ringwald 	  209,   198,   186,   176,   166,   157,   148,   140,   132,   124,   117,   111,
1698201da88SMatthias Ringwald 	  105,    99,    93,    88,    83,    78,    73,    69,    66,    62,    59,    55,
1708201da88SMatthias Ringwald 	   52,    49,    46,    44,    41,    39,    36,    34,    32,    30,    29,    27,
1718201da88SMatthias Ringwald 	   26,    24,    23,    22,    21,    20,    19,    18,    17,    16,    15,    14,
1728201da88SMatthias Ringwald 	   13,    13,    12,    11,    11,    10,     9,     9,     8,     8,     7,     7,
1738201da88SMatthias Ringwald 
1748201da88SMatthias Ringwald 	// Finetune 4 (* 0.971532), Offset 0x0480
1758201da88SMatthias Ringwald 	26612, 25120, 23690, 22384, 21078, 19897, 18778, 17721, 16726, 15793, 14923, 14083,
1768201da88SMatthias Ringwald 	13306, 12560, 11845, 11192, 10539,  9948,  9389,  8860,  8361,  7897,  7461,  7042,
1778201da88SMatthias Ringwald 	 6653,  6280,  5922,  5596,  5270,  4974,  4694,  4430,  4181,  3948,  3731,  3521,
1788201da88SMatthias Ringwald 	 3327,  3140,  2961,  2798,  2635,  2487,  2347,  2215,  2091,  1974,  1865,  1760,
1798201da88SMatthias Ringwald 	 1663,  1570,  1481,  1399,  1317,  1244,  1174,  1108,  1045,   987,   933,   880,
1808201da88SMatthias Ringwald 	  832,   785,   740,   700,   659,   622,   587,   554,   523,   494,   466,   440,
1818201da88SMatthias Ringwald 	  416,   392,   370,   350,   329,   311,   293,   277,   261,   247,   233,   220,
1828201da88SMatthias Ringwald 	  208,   196,   185,   175,   165,   155,   147,   139,   131,   123,   117,   110,
1838201da88SMatthias Ringwald 	  104,    98,    92,    87,    83,    78,    73,    69,    65,    61,    58,    54,
1848201da88SMatthias Ringwald 	   51,    49,    46,    44,    41,    39,    36,    34,    32,    30,    29,    27,
1858201da88SMatthias Ringwald 	   26,    24,    23,    21,    20,    19,    18,    17,    17,    16,    15,    14,
1868201da88SMatthias Ringwald 	   13,    13,    12,    11,    11,    10,     9,     9,     8,     8,     7,     7,
1878201da88SMatthias Ringwald 
1888201da88SMatthias Ringwald 	// Finetune 5 (* 0.964542), Offset 0x05a0
1898201da88SMatthias Ringwald 	26421, 24939, 23519, 22223, 20927, 19754, 18643, 17593, 16606, 15680, 14815, 13982,
1908201da88SMatthias Ringwald 	13210, 12470, 11760, 11112, 10463,  9877,  9321,  8797,  8301,  7840,  7408,  6991,
1918201da88SMatthias Ringwald 	 6605,  6235,  5880,  5556,  5232,  4938,  4661,  4398,  4151,  3920,  3704,  3496,
1928201da88SMatthias Ringwald 	 3303,  3117,  2940,  2778,  2616,  2469,  2330,  2199,  2076,  1960,  1852,  1748,
1938201da88SMatthias Ringwald 	 1651,  1559,  1470,  1389,  1308,  1235,  1165,  1100,  1038,   980,   926,   874,
1948201da88SMatthias Ringwald 	  826,   779,   735,   694,   654,   617,   583,   550,   519,   490,   463,   437,
1958201da88SMatthias Ringwald 	  413,   390,   367,   347,   327,   309,   291,   275,   259,   245,   231,   218,
1968201da88SMatthias Ringwald 	  206,   195,   183,   174,   164,   154,   146,   138,   130,   122,   116,   109,
1978201da88SMatthias Ringwald 	  103,    97,    92,    87,    82,    77,    72,    68,    65,    61,    58,    54,
1988201da88SMatthias Ringwald 	   51,    48,    45,    43,    41,    39,    36,    34,    32,    30,    29,    27,
1998201da88SMatthias Ringwald 	   26,    24,    23,    21,    20,    19,    18,    17,    16,    15,    14,    14,
2008201da88SMatthias Ringwald 	   13,    13,    12,    11,    11,    10,     9,     9,     8,     8,     7,     7,
2018201da88SMatthias Ringwald 
2028201da88SMatthias Ringwald 	// Finetune 6 (* 0.957603), Offset 0x06c0
2038201da88SMatthias Ringwald 	26231, 24760, 23350, 22063, 20776, 19612, 18509, 17467, 16486, 15567, 14709, 13881,
2048201da88SMatthias Ringwald 	13115, 12380, 11675, 11032, 10388,  9806,  9254,  8733,  8241,  7783,  7354,  6941,
2058201da88SMatthias Ringwald 	 6558,  6190,  5838,  5516,  5194,  4903,  4627,  4367,  4122,  3892,  3677,  3470,
2068201da88SMatthias Ringwald 	 3279,  3095,  2919,  2758,  2597,  2451,  2314,  2183,  2061,  1946,  1839,  1735,
2078201da88SMatthias Ringwald 	 1639,  1547,  1459,  1379,  1299,  1226,  1157,  1092,  1030,   973,   919,   868,
2088201da88SMatthias Ringwald 	  820,   774,   730,   689,   649,   613,   578,   546,   515,   486,   460,   434,
2098201da88SMatthias Ringwald 	  410,   387,   365,   345,   325,   306,   289,   273,   258,   243,   230,   216,
2108201da88SMatthias Ringwald 	  205,   193,   182,   172,   163,   153,   145,   137,   129,   122,   115,   108,
2118201da88SMatthias Ringwald 	  102,    97,    91,    86,    81,    77,    72,    68,    64,    60,    57,    54,
2128201da88SMatthias Ringwald 	   51,    48,    45,    43,    40,    38,    35,    34,    32,    30,    29,    27,
2138201da88SMatthias Ringwald 	   26,    24,    23,    21,    20,    19,    18,    17,    16,    15,    14,    13,
2148201da88SMatthias Ringwald 	   12,    12,    11,    11,    11,    10,     9,     9,     8,     8,     7,     7,
2158201da88SMatthias Ringwald 
2168201da88SMatthias Ringwald 	// Finetune 7 (* 0.950714), Offset 0x07e0
2178201da88SMatthias Ringwald 	26042, 24582, 23182, 21904, 20627, 19471, 18375, 17341, 16367, 15455, 14603, 13782,
2188201da88SMatthias Ringwald 	13021, 12291, 11591, 10952, 10313,  9735,  9188,  8671,  8182,  7727,  7301,  6891,
2198201da88SMatthias Ringwald 	 6510,  6145,  5796,  5476,  5157,  4868,  4594,  4335,  4092,  3864,  3651,  3445,
2208201da88SMatthias Ringwald 	 3255,  3073,  2898,  2738,  2578,  2434,  2297,  2168,  2046,  1932,  1825,  1723,
2218201da88SMatthias Ringwald 	 1628,  1536,  1449,  1369,  1289,  1217,  1148,  1084,  1023,   966,   913,   861,
2228201da88SMatthias Ringwald 	  814,   768,   724,   685,   645,   608,   574,   542,   511,   483,   456,   431,
2238201da88SMatthias Ringwald 	  407,   384,   362,   342,   322,   304,   287,   271,   256,   241,   228,   215,
2248201da88SMatthias Ringwald 	  203,   192,   181,   171,   162,   152,   144,   136,   128,   121,   114,   107,
2258201da88SMatthias Ringwald 	  102,    96,    90,    86,    81,    76,    71,    68,    64,    60,    57,    53,
2268201da88SMatthias Ringwald 	   50,    48,    45,    43,    40,    38,    35,    33,    31,    29,    29,    27,
2278201da88SMatthias Ringwald 	   26,    24,    23,    21,    20,    19,    18,    17,    16,    15,    14,    13,
2288201da88SMatthias Ringwald 	   12,    12,    11,    10,    10,    10,     9,     9,     8,     8,     7,     7,
2298201da88SMatthias Ringwald 
2308201da88SMatthias Ringwald 	// Finetune -8 (* 1.059463), Offset 0x0900
2318201da88SMatthias Ringwald 	29021, 27393, 25834, 24410, 22986, 21698, 20477, 19325, 18240, 17223, 16273, 15358,
2328201da88SMatthias Ringwald 	14510, 13697, 12917, 12205, 11493, 10849, 10239,  9662,  9118,  8611,  8137,  7679,
2338201da88SMatthias Ringwald 	 7255,  6848,  6458,  6103,  5747,  5424,  5119,  4831,  4560,  4306,  4068,  3839,
2348201da88SMatthias Ringwald 	 3628,  3424,  3229,  3051,  2873,  2712,  2560,  2416,  2280,  2153,  2034,  1920,
2358201da88SMatthias Ringwald 	 1814,  1712,  1615,  1526,  1437,  1356,  1280,  1208,  1140,  1076,  1017,   960,
2368201da88SMatthias Ringwald 	  907,   856,   807,   763,   718,   678,   640,   604,   570,   538,   509,   480,
2378201da88SMatthias Ringwald 	  453,   428,   404,   381,   359,   339,   320,   302,   285,   269,   254,   239,
2388201da88SMatthias Ringwald 	  227,   214,   201,   191,   180,   170,   160,   152,   143,   135,   127,   120,
2398201da88SMatthias Ringwald 	  113,   107,   101,    95,    90,    85,    79,    75,    71,    67,    64,    59,
2408201da88SMatthias Ringwald 	   56,    53,    50,    48,    44,    42,    39,    37,    35,    33,    32,    30,
2418201da88SMatthias Ringwald 	   29,    26,    25,    23,    22,    21,    20,    19,    18,    17,    16,    15,
2428201da88SMatthias Ringwald 	   14,    14,    13,    12,    12,    11,    10,    10,     8,     8,     7,     7,
2438201da88SMatthias Ringwald 
2448201da88SMatthias Ringwald 	// Finetune -7 (* 1.051841), Offset 0x0a20
2458201da88SMatthias Ringwald 	28812, 27196, 25648, 24234, 22821, 21542, 20330, 19186, 18108, 17099, 16156, 15247,
2468201da88SMatthias Ringwald 	14406, 13598, 12824, 12117, 11410, 10771, 10165,  9593,  9052,  8549,  8078,  7624,
2478201da88SMatthias Ringwald 	 7203,  6799,  6412,  6059,  5705,  5385,  5082,  4796,  4527,  4275,  4039,  3812,
2488201da88SMatthias Ringwald 	 3602,  3400,  3206,  3029,  2853,  2693,  2541,  2398,  2264,  2137,  2020,  1906,
2498201da88SMatthias Ringwald 	 1801,  1700,  1603,  1515,  1426,  1346,  1271,  1199,  1132,  1069,  1010,   953,
2508201da88SMatthias Ringwald 	  900,   850,   802,   757,   713,   673,   635,   600,   566,   534,   505,   476,
2518201da88SMatthias Ringwald 	  450,   425,   401,   379,   357,   337,   318,   300,   283,   267,   252,   238,
2528201da88SMatthias Ringwald 	  225,   212,   200,   189,   179,   168,   159,   150,   142,   134,   126,   119,
2538201da88SMatthias Ringwald 	  113,   106,   100,    95,    89,    84,    79,    75,    70,    66,    63,    59,
2548201da88SMatthias Ringwald 	   56,    53,    49,    47,    44,    42,    39,    37,    35,    33,    32,    29,
2558201da88SMatthias Ringwald 	   28,    26,    25,    23,    22,    21,    20,    19,    18,    17,    16,    15,
2568201da88SMatthias Ringwald 	   14,    14,    13,    12,    12,    11,     9,     9,     8,     8,     7,     7,
2578201da88SMatthias Ringwald 
2588201da88SMatthias Ringwald 	// Finetune -6 (* 1.044274), Offset 0x0b40
2598201da88SMatthias Ringwald 	28605, 27001, 25464, 24060, 22657, 21387, 20184, 19048, 17978, 16976, 16040, 15138,
2608201da88SMatthias Ringwald 	14302, 13500, 12732, 12030, 11328, 10693, 10092,  9524,  8987,  8488,  8020,  7569,
2618201da88SMatthias Ringwald 	 7151,  6750,  6366,  6015,  5664,  5347,  5046,  4762,  4495,  4244,  4010,  3784,
2628201da88SMatthias Ringwald 	 3576,  3375,  3183,  3008,  2832,  2673,  2523,  2381,  2247,  2122,  2005,  1892,
2638201da88SMatthias Ringwald 	 1788,  1688,  1591,  1504,  1416,  1337,  1261,  1190,  1124,  1061,  1003,   946,
2648201da88SMatthias Ringwald 	  894,   844,   796,   752,   708,   668,   631,   595,   562,   530,   501,   473,
2658201da88SMatthias Ringwald 	  447,   422,   398,   376,   354,   334,   315,   298,   281,   265,   251,   236,
2668201da88SMatthias Ringwald 	  223,   211,   198,   188,   178,   167,   158,   149,   141,   133,   125,   118,
2678201da88SMatthias Ringwald 	  112,   105,    99,    94,    89,    84,    78,    74,    70,    66,    63,    58,
2688201da88SMatthias Ringwald 	   55,    52,    49,    47,    44,    42,    39,    37,    34,    32,    31,    29,
2698201da88SMatthias Ringwald 	   28,    26,    25,    23,    22,    21,    20,    19,    18,    17,    16,    15,
2708201da88SMatthias Ringwald 	   14,    14,    13,    11,    11,    10,     9,     9,     8,     8,     7,     7,
2718201da88SMatthias Ringwald 
2728201da88SMatthias Ringwald 	// Finetune -5 (* 1.036761), Offset 0x0c60
2738201da88SMatthias Ringwald 	28399, 26806, 25280, 23887, 22494, 21233, 20039, 18911, 17849, 16854, 15925, 15029,
2748201da88SMatthias Ringwald 	14199, 13403, 12640, 11943, 11247, 10616, 10019,  9455,  8922,  8427,  7962,  7514,
2758201da88SMatthias Ringwald 	 7100,  6702,  6320,  5972,  5623,  5308,  5010,  4728,  4462,  4213,  3981,  3757,
2768201da88SMatthias Ringwald 	 3550,  3351,  3160,  2986,  2812,  2654,  2505,  2364,  2231,  2107,  1991,  1879,
2778201da88SMatthias Ringwald 	 1775,  1675,  1580,  1493,  1406,  1327,  1252,  1182,  1116,  1053,   995,   939,
2788201da88SMatthias Ringwald 	  887,   838,   790,   746,   703,   664,   626,   591,   558,   527,   498,   470,
2798201da88SMatthias Ringwald 	  444,   419,   395,   373,   351,   332,   313,   295,   279,   263,   249,   234,
2808201da88SMatthias Ringwald 	  222,   209,   197,   187,   176,   166,   157,   148,   140,   132,   124,   117,
2818201da88SMatthias Ringwald 	  111,   105,    98,    93,    88,    83,    78,    74,    69,    65,    62,    58,
2828201da88SMatthias Ringwald 	   55,    52,    49,    47,    44,    41,    38,    36,    34,    32,    31,    29,
2838201da88SMatthias Ringwald 	   28,    26,    25,    23,    22,    21,    20,    19,    18,    17,    16,    15,
2848201da88SMatthias Ringwald 	   13,    13,    12,    11,    11,    10,     9,     9,     8,     8,     7,     7,
2858201da88SMatthias Ringwald 
2868201da88SMatthias Ringwald 	// Finetune -4 (* 1.029302), Offset 0x0d80
2878201da88SMatthias Ringwald 	28195, 26614, 25099, 23715, 22332, 21080, 19894, 18774, 17720, 16732, 15810, 14921,
2888201da88SMatthias Ringwald 	14097, 13307, 12549, 11858, 11166, 10540,  9947,  9387,  8858,  8366,  7905,  7460,
2898201da88SMatthias Ringwald 	 7049,  6653,  6275,  5929,  5583,  5270,  4974,  4694,  4430,  4183,  3953,  3730,
2908201da88SMatthias Ringwald 	 3524,  3327,  3137,  2964,  2791,  2635,  2487,  2347,  2215,  2092,  1976,  1865,
2918201da88SMatthias Ringwald 	 1762,  1663,  1569,  1482,  1396,  1318,  1243,  1173,  1108,  1046,   988,   933,
2928201da88SMatthias Ringwald 	  881,   832,   784,   741,   698,   659,   622,   587,   554,   523,   494,   466,
2938201da88SMatthias Ringwald 	  441,   416,   392,   371,   349,   329,   311,   293,   277,   261,   247,   233,
2948201da88SMatthias Ringwald 	  220,   208,   196,   185,   175,   165,   155,   147,   139,   131,   124,   116,
2958201da88SMatthias Ringwald 	  110,   104,    98,    93,    87,    82,    77,    73,    69,    65,    62,    58,
2968201da88SMatthias Ringwald 	   55,    51,    48,    46,    43,    41,    38,    36,    34,    32,    31,    29,
2978201da88SMatthias Ringwald 	   28,    26,    25,    23,    22,    21,    20,    19,    17,    16,    15,    14,
2988201da88SMatthias Ringwald 	   13,    13,    12,    11,    11,    10,     9,     9,     8,     8,     7,     7,
2998201da88SMatthias Ringwald 
3008201da88SMatthias Ringwald 	// Finetune -3 (* 1.021897), Offset 0x0ea0
3018201da88SMatthias Ringwald 	27992, 26422, 24918, 23545, 22171, 20928, 19751, 18639, 17593, 16612, 15696, 14813,
3028201da88SMatthias Ringwald 	13996, 13211, 12459, 11772, 11086, 10464,  9876,  9320,  8794,  8306,  7848,  7407,
3038201da88SMatthias Ringwald 	 6998,  6606,  6229,  5886,  5543,  5232,  4938,  4660,  4398,  4153,  3924,  3703,
3048201da88SMatthias Ringwald 	 3499,  3303,  3115,  2943,  2771,  2616,  2469,  2330,  2199,  2076,  1962,  1852,
3058201da88SMatthias Ringwald 	 1749,  1651,  1557,  1472,  1386,  1308,  1234,  1165,  1100,  1038,   981,   926,
3068201da88SMatthias Ringwald 	  875,   826,   779,   736,   693,   654,   617,   582,   550,   519,   491,   463,
3078201da88SMatthias Ringwald 	  437,   413,   389,   368,   346,   327,   309,   291,   275,   260,   245,   231,
3088201da88SMatthias Ringwald 	  219,   206,   194,   184,   174,   164,   154,   146,   138,   130,   123,   115,
3098201da88SMatthias Ringwald 	  109,   103,    97,    92,    87,    82,    77,    73,    68,    64,    61,    57,
3108201da88SMatthias Ringwald 	   54,    51,    48,    46,    43,    41,    38,    36,    34,    32,    31,    29,
3118201da88SMatthias Ringwald 	   28,    26,    25,    22,    21,    20,    19,    18,    17,    16,    15,    14,
3128201da88SMatthias Ringwald 	   13,    13,    12,    11,    11,    10,     9,     9,     8,     8,     7,     7,
3138201da88SMatthias Ringwald 
3148201da88SMatthias Ringwald 	// Finetune -2 (* 1.014545), Offset 0x0fc0
3158201da88SMatthias Ringwald 	27790, 26232, 24739, 23375, 22012, 20778, 19609, 18505, 17466, 16492, 15583, 14707,
3168201da88SMatthias Ringwald 	13895, 13116, 12369, 11688, 11006, 10389,  9805,  9253,  8731,  8246,  7792,  7353,
3178201da88SMatthias Ringwald 	 6948,  6558,  6185,  5844,  5503,  5194,  4902,  4626,  4367,  4123,  3896,  3677,
3188201da88SMatthias Ringwald 	 3474,  3279,  3092,  2922,  2751,  2597,  2451,  2313,  2183,  2062,  1948,  1838,
3198201da88SMatthias Ringwald 	 1737,  1640,  1546,  1461,  1376,  1299,  1226,  1157,  1092,  1031,   974,   919,
3208201da88SMatthias Ringwald 	  868,   820,   773,   730,   688,   649,   613,   578,   546,   515,   487,   460,
3218201da88SMatthias Ringwald 	  434,   410,   387,   365,   344,   325,   306,   289,   273,   258,   243,   229,
3228201da88SMatthias Ringwald 	  217,   205,   193,   183,   172,   162,   153,   145,   137,   129,   122,   115,
3238201da88SMatthias Ringwald 	  109,   102,    96,    91,    86,    81,    76,    72,    68,    64,    61,    57,
3248201da88SMatthias Ringwald 	   54,    51,    48,    46,    43,    41,    38,    36,    33,    31,    30,    28,
3258201da88SMatthias Ringwald 	   27,    25,    24,    22,    21,    20,    19,    18,    17,    16,    15,    14,
3268201da88SMatthias Ringwald 	   13,    13,    12,    11,    11,    10,     9,     9,     8,     8,     7,     7,
3278201da88SMatthias Ringwald 
3288201da88SMatthias Ringwald 	// Finetune -1 (* 1.007246), Offset 0x10e0
3298201da88SMatthias Ringwald 	27590, 26043, 24561, 23207, 21853, 20628, 19468, 18372, 17341, 16374, 15471, 14601,
3308201da88SMatthias Ringwald 	13795, 13022, 12280, 11603, 10927, 10314,  9734,  9186,  8668,  8187,  7736,  7301,
3318201da88SMatthias Ringwald 	 6898,  6511,  6140,  5802,  5463,  5157,  4867,  4593,  4335,  4093,  3868,  3650,
3328201da88SMatthias Ringwald 	 3449,  3255,  3070,  2901,  2732,  2579,  2434,  2297,  2168,  2047,  1934,  1825,
3338201da88SMatthias Ringwald 	 1724,  1628,  1535,  1450,  1366,  1289,  1217,  1148,  1084,  1023,   967,   913,
3348201da88SMatthias Ringwald 	  862,   814,   768,   725,   683,   645,   608,   574,   542,   512,   483,   456,
3358201da88SMatthias Ringwald 	  431,   407,   384,   363,   341,   322,   304,   287,   271,   256,   242,   228,
3368201da88SMatthias Ringwald 	  216,   203,   191,   181,   171,   161,   152,   144,   136,   128,   121,   114,
3378201da88SMatthias Ringwald 	  108,   102,    96,    91,    86,    81,    76,    72,    67,    63,    60,    56,
3388201da88SMatthias Ringwald 	   53,    50,    47,    45,    42,    40,    37,    35,    33,    31,    30,    28,
3398201da88SMatthias Ringwald 	   27,    25,    24,    22,    21,    20,    19,    18,    17,    16,    15,    14,
340a4cd9b30SMilanka Ringwald 	   13,    13,    12,    11,    11,    10,     9,     9,     8,     8,     7,     7
341a4cd9b30SMilanka Ringwald };
342a4cd9b30SMilanka Ringwald 
3438201da88SMatthias Ringwald static const short * periodtable_finetune_ptr[]=
3448201da88SMatthias Ringwald {
3458201da88SMatthias Ringwald 	&periodtable[0x0000], &periodtable[0x0090], &periodtable[0x0120], &periodtable[0x01B0],
3468201da88SMatthias Ringwald 	&periodtable[0x0240], &periodtable[0x02D0], &periodtable[0x0360], &periodtable[0x03F0],
3478201da88SMatthias Ringwald 	&periodtable[0x0480], &periodtable[0x0510], &periodtable[0x05A0], &periodtable[0x0630],
3488201da88SMatthias Ringwald 	&periodtable[0x06C0], &periodtable[0x0750], &periodtable[0x07E0], &periodtable[0x0870]
3498201da88SMatthias Ringwald };
3508201da88SMatthias Ringwald 
351a4cd9b30SMilanka Ringwald static const short sintable[]={
352a4cd9b30SMilanka Ringwald 	  0,  24,  49,  74,  97, 120, 141, 161,
353a4cd9b30SMilanka Ringwald 	180, 197, 212, 224, 235, 244, 250, 253,
354a4cd9b30SMilanka Ringwald 	255, 253, 250, 244, 235, 224, 212, 197,
355a4cd9b30SMilanka Ringwald 	180, 161, 141, 120,  97,  74,  49,  24
356a4cd9b30SMilanka Ringwald };
357a4cd9b30SMilanka Ringwald 
3588201da88SMatthias Ringwald static const muchar InvertLoopTable[]={
3598201da88SMatthias Ringwald 	  0,   5,   6,   7,   8,  10,  11, 13,
3608201da88SMatthias Ringwald 	 16,  19,  22,  26,  32,  43,  64, 128
3618201da88SMatthias Ringwald };
3628201da88SMatthias Ringwald 
363a4cd9b30SMilanka Ringwald typedef struct modtype_
364a4cd9b30SMilanka Ringwald {
365a4cd9b30SMilanka Ringwald 	unsigned char signature[5];
366a4cd9b30SMilanka Ringwald 	int numberofchannels;
367a4cd9b30SMilanka Ringwald }modtype;
368a4cd9b30SMilanka Ringwald 
3698201da88SMatthias Ringwald static modtype modlist[]=
370a4cd9b30SMilanka Ringwald {
371a4cd9b30SMilanka Ringwald 	{ "M!K!",4},
372a4cd9b30SMilanka Ringwald 	{ "M.K.",4},
3738201da88SMatthias Ringwald 	{ "M&K!",4},
3748201da88SMatthias Ringwald 	{ "PATT",4},
3758201da88SMatthias Ringwald 	{ "NSMS",4},
3768201da88SMatthias Ringwald 	{ "LARD",4},
3778201da88SMatthias Ringwald 	{ "FEST",4},
3788201da88SMatthias Ringwald 	{ "FIST",4},
3798201da88SMatthias Ringwald 	{ "N.T.",4},
3808201da88SMatthias Ringwald 	{ "OKTA",8},
3818201da88SMatthias Ringwald 	{ "OCTA",8},
3828201da88SMatthias Ringwald 	{ "$CHN",-1},
3838201da88SMatthias Ringwald 	{ "$$CH",-1},
3848201da88SMatthias Ringwald 	{ "$$CN",-1},
3858201da88SMatthias Ringwald 	{ "$$$C",-1},
3868201da88SMatthias Ringwald 	{ "FLT$",-1},
3878201da88SMatthias Ringwald 	{ "EXO$",-1},
3888201da88SMatthias Ringwald 	{ "CD$1",-1},
3898201da88SMatthias Ringwald 	{ "TDZ$",-1},
3908201da88SMatthias Ringwald 	{ "FA0$",-1},
391a4cd9b30SMilanka Ringwald 	{ "",0}
392a4cd9b30SMilanka Ringwald };
393a4cd9b30SMilanka Ringwald 
3948201da88SMatthias Ringwald #ifdef HXCMOD_BIGENDIAN_MACHINE
3958201da88SMatthias Ringwald 
3968201da88SMatthias Ringwald #define GET_BGI_W( big_endian_word ) ( big_endian_word )
3978201da88SMatthias Ringwald 
3988201da88SMatthias Ringwald #else
3998201da88SMatthias Ringwald 
4008201da88SMatthias Ringwald #define GET_BGI_W( big_endian_word ) ( (big_endian_word >> 8) | ((big_endian_word&0xFF) << 8) )
4018201da88SMatthias Ringwald 
4028201da88SMatthias Ringwald #endif
4038201da88SMatthias Ringwald 
4048201da88SMatthias Ringwald 
405a4cd9b30SMilanka Ringwald ///////////////////////////////////////////////////////////////////////////////////
406a4cd9b30SMilanka Ringwald 
407a4cd9b30SMilanka Ringwald static void memcopy( void * dest, void *source, unsigned long size )
408a4cd9b30SMilanka Ringwald {
409a4cd9b30SMilanka Ringwald 	unsigned long i;
410a4cd9b30SMilanka Ringwald 	unsigned char * d,*s;
411a4cd9b30SMilanka Ringwald 
412a4cd9b30SMilanka Ringwald 	d=(unsigned char*)dest;
413a4cd9b30SMilanka Ringwald 	s=(unsigned char*)source;
414a4cd9b30SMilanka Ringwald 	for(i=0;i<size;i++)
415a4cd9b30SMilanka Ringwald 	{
416a4cd9b30SMilanka Ringwald 		d[i]=s[i];
417a4cd9b30SMilanka Ringwald 	}
418a4cd9b30SMilanka Ringwald }
419a4cd9b30SMilanka Ringwald 
420a4cd9b30SMilanka Ringwald static void memclear( void * dest, unsigned char value, unsigned long size )
421a4cd9b30SMilanka Ringwald {
422a4cd9b30SMilanka Ringwald 	unsigned long i;
423a4cd9b30SMilanka Ringwald 	unsigned char * d;
424a4cd9b30SMilanka Ringwald 
425a4cd9b30SMilanka Ringwald 	d = (unsigned char*)dest;
426a4cd9b30SMilanka Ringwald 	for(i=0;i<size;i++)
427a4cd9b30SMilanka Ringwald 	{
428a4cd9b30SMilanka Ringwald 		d[i]=value;
429a4cd9b30SMilanka Ringwald 	}
430a4cd9b30SMilanka Ringwald }
431a4cd9b30SMilanka Ringwald 
4328201da88SMatthias Ringwald static int getnote( modcontext * mod, unsigned short period )
433a4cd9b30SMilanka Ringwald {
434*4aa7d471SMatthias Ringwald // BK4BSTACK_CHANGE START
435*4aa7d471SMatthias Ringwald 	(void) mod;
436*4aa7d471SMatthias Ringwald // BK4BSTACK_CHANGE END
437*4aa7d471SMatthias Ringwald 
438a4cd9b30SMilanka Ringwald 	int i;
4398201da88SMatthias Ringwald 	const short * ptr;
440a4cd9b30SMilanka Ringwald 
4418201da88SMatthias Ringwald 	ptr = periodtable_finetune_ptr[0];
4428201da88SMatthias Ringwald 
4438201da88SMatthias Ringwald 	for(i = 0; i < MAXNOTES; i++)
444a4cd9b30SMilanka Ringwald 	{
4458201da88SMatthias Ringwald 		if(period >= ptr[i])
446a4cd9b30SMilanka Ringwald 		{
447a4cd9b30SMilanka Ringwald 			return i;
448a4cd9b30SMilanka Ringwald 		}
449a4cd9b30SMilanka Ringwald 	}
450a4cd9b30SMilanka Ringwald 
451a4cd9b30SMilanka Ringwald 	return MAXNOTES;
452a4cd9b30SMilanka Ringwald }
453a4cd9b30SMilanka Ringwald 
4548201da88SMatthias Ringwald static void doFunk(channel * cptr)
455a4cd9b30SMilanka Ringwald {
4568201da88SMatthias Ringwald 	if(cptr->funkspeed)
4578201da88SMatthias Ringwald 	{
4588201da88SMatthias Ringwald 		cptr->funkoffset += InvertLoopTable[cptr->funkspeed];
4598201da88SMatthias Ringwald 		if( cptr->funkoffset > 128 )
4608201da88SMatthias Ringwald 		{
4618201da88SMatthias Ringwald 			cptr->funkoffset = 0;
4628201da88SMatthias Ringwald 			if( cptr->sampdata && cptr->length && (cptr->replen > 1) )
4638201da88SMatthias Ringwald 			{
4648201da88SMatthias Ringwald 				if( ( (cptr->samppos) >> 11 ) >= (unsigned long)(cptr->replen+cptr->reppnt) )
4658201da88SMatthias Ringwald 				{
4668201da88SMatthias Ringwald 					cptr->samppos = ((unsigned long)(cptr->reppnt)<<11) + (cptr->samppos % ((unsigned long)(cptr->replen+cptr->reppnt)<<11));
4678201da88SMatthias Ringwald 				}
468a4cd9b30SMilanka Ringwald 
4698201da88SMatthias Ringwald #ifndef HXCMOD_MOD_FILE_IN_ROM
4708201da88SMatthias Ringwald 				// Note : Directly modify the sample in the mod buffer...
4718201da88SMatthias Ringwald 				// The current Invert Loop effect implementation can't be played from ROM.
4728201da88SMatthias Ringwald 				cptr->sampdata[cptr->samppos >> 10] = -1 - cptr->sampdata[cptr->samppos >> 10];
4738201da88SMatthias Ringwald #endif
4748201da88SMatthias Ringwald 			}
4758201da88SMatthias Ringwald 		}
4768201da88SMatthias Ringwald 	}
4778201da88SMatthias Ringwald }
4788201da88SMatthias Ringwald 
4798201da88SMatthias Ringwald static void worknote( note * nptr, channel * cptr,char t,modcontext * mod )
4808201da88SMatthias Ringwald {
481*4aa7d471SMatthias Ringwald 	// BK4BSTACK_CHANGE START
482*4aa7d471SMatthias Ringwald 	(void) t;
483*4aa7d471SMatthias Ringwald 	// BK4BSTACK_CHANGE END
484*4aa7d471SMatthias Ringwald 
4858201da88SMatthias Ringwald 	muint sample, period, effect, operiod;
4868201da88SMatthias Ringwald 	muint curnote, arpnote;
4878201da88SMatthias Ringwald 	muchar effect_op;
4888201da88SMatthias Ringwald 	muchar effect_param,effect_param_l,effect_param_h;
4898201da88SMatthias Ringwald 	muint enable_nxt_smp;
4908201da88SMatthias Ringwald 	const short * period_table_ptr;
4918201da88SMatthias Ringwald 
4928201da88SMatthias Ringwald 	sample = (nptr->sampperiod & 0xF0) | (nptr->sampeffect >> 4);
493a4cd9b30SMilanka Ringwald 	period = ((nptr->sampperiod & 0xF) << 8) | nptr->period;
494a4cd9b30SMilanka Ringwald 	effect = ((nptr->sampeffect & 0xF) << 8) | nptr->effect;
4958201da88SMatthias Ringwald 	effect_op = nptr->sampeffect & 0xF;
4968201da88SMatthias Ringwald 	effect_param = nptr->effect;
4978201da88SMatthias Ringwald 	effect_param_l = effect_param & 0x0F;
4988201da88SMatthias Ringwald 	effect_param_h = effect_param >> 4;
4998201da88SMatthias Ringwald 
5008201da88SMatthias Ringwald 	enable_nxt_smp = 0;
501a4cd9b30SMilanka Ringwald 
502a4cd9b30SMilanka Ringwald 	operiod = cptr->period;
503a4cd9b30SMilanka Ringwald 
5048201da88SMatthias Ringwald 	if ( period || sample )
505a4cd9b30SMilanka Ringwald 	{
5068201da88SMatthias Ringwald 		if( sample && ( sample < 32 ) )
507a4cd9b30SMilanka Ringwald 		{
5088201da88SMatthias Ringwald 			cptr->sampnum = sample - 1;
509a4cd9b30SMilanka Ringwald 		}
510a4cd9b30SMilanka Ringwald 
5118201da88SMatthias Ringwald 		if( period || sample )
512a4cd9b30SMilanka Ringwald 		{
5138201da88SMatthias Ringwald 			if( period )
5148201da88SMatthias Ringwald 			{
5158201da88SMatthias Ringwald 				if( ( effect_op != EFFECT_TONE_PORTAMENTO ) || ( ( effect_op == EFFECT_TONE_PORTAMENTO ) && !cptr->sampdata ) )
5168201da88SMatthias Ringwald 				{
5178201da88SMatthias Ringwald 					// Not a Tone Partamento effect or no sound currently played :
5188201da88SMatthias Ringwald 					if ( ( effect_op != EFFECT_EXTENDED || effect_param_h != EFFECT_E_NOTE_DELAY ) || ( ( effect_op == EFFECT_EXTENDED && effect_param_h == EFFECT_E_NOTE_DELAY ) && !effect_param_l ) )
5198201da88SMatthias Ringwald 					{
5208201da88SMatthias Ringwald 						// Immediately (re)trigger the new note
521afc6fe18SMatthias Ringwald 						cptr->sampdata = mod->sampledata[cptr->sampnum];
5228201da88SMatthias Ringwald 						cptr->length = GET_BGI_W( mod->song.samples[cptr->sampnum].length );
5238201da88SMatthias Ringwald 						cptr->reppnt = GET_BGI_W( mod->song.samples[cptr->sampnum].reppnt );
5248201da88SMatthias Ringwald 						cptr->replen = GET_BGI_W( mod->song.samples[cptr->sampnum].replen );
5258201da88SMatthias Ringwald 
5268201da88SMatthias Ringwald 						cptr->lst_sampdata = cptr->sampdata;
5278201da88SMatthias Ringwald 						cptr->lst_length = cptr->length;
5288201da88SMatthias Ringwald 						cptr->lst_reppnt = cptr->reppnt;
5298201da88SMatthias Ringwald 						cptr->lst_replen = cptr->replen;
5308201da88SMatthias Ringwald 					}
5318201da88SMatthias Ringwald 					else
5328201da88SMatthias Ringwald 					{
5338201da88SMatthias Ringwald 						cptr->dly_sampdata = mod->sampledata[cptr->sampnum];
5348201da88SMatthias Ringwald 						cptr->dly_length = GET_BGI_W( mod->song.samples[cptr->sampnum].length );
5358201da88SMatthias Ringwald 						cptr->dly_reppnt = GET_BGI_W( mod->song.samples[cptr->sampnum].reppnt );
5368201da88SMatthias Ringwald 						cptr->dly_replen = GET_BGI_W( mod->song.samples[cptr->sampnum].replen );
5378201da88SMatthias Ringwald 						cptr->note_delay = effect_param_l;
5388201da88SMatthias Ringwald 					}
5398201da88SMatthias Ringwald 					// Cancel any delayed note...
5408201da88SMatthias Ringwald 					cptr->update_nxt_repeat = 0;
5418201da88SMatthias Ringwald 				}
5428201da88SMatthias Ringwald 				else
5438201da88SMatthias Ringwald 				{
5448201da88SMatthias Ringwald 					// Partamento effect - Play the new note after the current sample.
5458201da88SMatthias Ringwald 					if( effect_op == EFFECT_TONE_PORTAMENTO )
5468201da88SMatthias Ringwald 						enable_nxt_smp = 1;
5478201da88SMatthias Ringwald 				}
5488201da88SMatthias Ringwald 			}
5498201da88SMatthias Ringwald 			else // Note without period : Trigger it after the current sample.
5508201da88SMatthias Ringwald 				enable_nxt_smp = 1;
5518201da88SMatthias Ringwald 
5528201da88SMatthias Ringwald 			if ( enable_nxt_smp )
5538201da88SMatthias Ringwald 			{
5548201da88SMatthias Ringwald 				// Prepare the next sample retrigger after the current one
5558201da88SMatthias Ringwald 				cptr->nxt_sampdata = mod->sampledata[cptr->sampnum];
5568201da88SMatthias Ringwald 				cptr->nxt_length = GET_BGI_W( mod->song.samples[cptr->sampnum].length );
5578201da88SMatthias Ringwald 				cptr->nxt_reppnt = GET_BGI_W( mod->song.samples[cptr->sampnum].reppnt );
5588201da88SMatthias Ringwald 				cptr->nxt_replen = GET_BGI_W( mod->song.samples[cptr->sampnum].replen );
5598201da88SMatthias Ringwald 
5608201da88SMatthias Ringwald 				if(cptr->nxt_replen < 2)   // Protracker : don't play the sample if not looped...
5618201da88SMatthias Ringwald 					cptr->nxt_sampdata = 0;
5628201da88SMatthias Ringwald 
5638201da88SMatthias Ringwald 				cptr->update_nxt_repeat = 1;
5648201da88SMatthias Ringwald 			}
565a4cd9b30SMilanka Ringwald 
566a4cd9b30SMilanka Ringwald 			cptr->finetune = (mod->song.samples[cptr->sampnum].finetune) & 0xF;
567a4cd9b30SMilanka Ringwald 
5688201da88SMatthias Ringwald 			if( effect_op != EFFECT_VIBRATO && effect_op != EFFECT_VOLSLIDE_VIBRATO )
569a4cd9b30SMilanka Ringwald 			{
570a4cd9b30SMilanka Ringwald 				cptr->vibraperiod = 0;
571a4cd9b30SMilanka Ringwald 				cptr->vibrapointeur = 0;
572a4cd9b30SMilanka Ringwald 			}
573a4cd9b30SMilanka Ringwald 		}
574a4cd9b30SMilanka Ringwald 
5758201da88SMatthias Ringwald 		if( (sample != 0) && ( effect_op != EFFECT_VOLSLIDE_TONEPORTA ) )
576a4cd9b30SMilanka Ringwald 		{
577a4cd9b30SMilanka Ringwald 			cptr->volume = mod->song.samples[cptr->sampnum].volume;
578a4cd9b30SMilanka Ringwald 			cptr->volumeslide = 0;
5798201da88SMatthias Ringwald #ifdef HXCMOD_USE_PRECALC_VOLUME_TABLE
5808201da88SMatthias Ringwald 			cptr->volume_table = mod->volume_selection_table[cptr->volume];
5818201da88SMatthias Ringwald #endif
582a4cd9b30SMilanka Ringwald 		}
583a4cd9b30SMilanka Ringwald 
5848201da88SMatthias Ringwald 		if( ( effect_op != EFFECT_TONE_PORTAMENTO ) && ( effect_op != EFFECT_VOLSLIDE_TONEPORTA ) )
585a4cd9b30SMilanka Ringwald 		{
586a4cd9b30SMilanka Ringwald 			if ( period != 0 )
587a4cd9b30SMilanka Ringwald 				cptr->samppos = 0;
588a4cd9b30SMilanka Ringwald 		}
589a4cd9b30SMilanka Ringwald 
590a4cd9b30SMilanka Ringwald 		cptr->decalperiod = 0;
591a4cd9b30SMilanka Ringwald 		if( period )
592a4cd9b30SMilanka Ringwald 		{
593a4cd9b30SMilanka Ringwald 			if( cptr->finetune )
594a4cd9b30SMilanka Ringwald 			{
5958201da88SMatthias Ringwald 				period_table_ptr = periodtable_finetune_ptr[cptr->finetune&0xF];
5968201da88SMatthias Ringwald 				period = period_table_ptr[getnote(mod,period)];
597a4cd9b30SMilanka Ringwald 			}
598a4cd9b30SMilanka Ringwald 
599a4cd9b30SMilanka Ringwald 			cptr->period = period;
600a4cd9b30SMilanka Ringwald 		}
601a4cd9b30SMilanka Ringwald 	}
602a4cd9b30SMilanka Ringwald 
603a4cd9b30SMilanka Ringwald 	cptr->effect = 0;
604a4cd9b30SMilanka Ringwald 	cptr->parameffect = 0;
605a4cd9b30SMilanka Ringwald 	cptr->effect_code = effect;
606a4cd9b30SMilanka Ringwald 
6078201da88SMatthias Ringwald #ifdef EFFECTS_USAGE_STATE
6088201da88SMatthias Ringwald 	if(effect_op || ((effect_op==EFFECT_ARPEGGIO) && effect_param))
6098201da88SMatthias Ringwald 	{
6108201da88SMatthias Ringwald 		mod->effects_event_counts[ effect_op ]++;
6118201da88SMatthias Ringwald 	}
6128201da88SMatthias Ringwald 
6138201da88SMatthias Ringwald 	if(effect_op == 0xE)
6148201da88SMatthias Ringwald 		mod->effects_event_counts[ 0x10 + effect_param_h ]++;
6158201da88SMatthias Ringwald #endif
6168201da88SMatthias Ringwald 
6178201da88SMatthias Ringwald 	switch ( effect_op )
618a4cd9b30SMilanka Ringwald 	{
619a4cd9b30SMilanka Ringwald 		case EFFECT_ARPEGGIO:
620a4cd9b30SMilanka Ringwald 			/*
621a4cd9b30SMilanka Ringwald 			[0]: Arpeggio
622a4cd9b30SMilanka Ringwald 			Where [0][x][y] means "play note, note+x semitones, note+y
623a4cd9b30SMilanka Ringwald 			semitones, then return to original note". The fluctuations are
624a4cd9b30SMilanka Ringwald 			carried out evenly spaced in one pattern division. They are usually
625a4cd9b30SMilanka Ringwald 			used to simulate chords, but this doesn't work too well. They are
626a4cd9b30SMilanka Ringwald 			also used to produce heavy vibrato. A major chord is when x=4, y=7.
627a4cd9b30SMilanka Ringwald 			A minor chord is when x=3, y=7.
628a4cd9b30SMilanka Ringwald 			*/
629a4cd9b30SMilanka Ringwald 
6308201da88SMatthias Ringwald 			if( effect_param )
631a4cd9b30SMilanka Ringwald 			{
632a4cd9b30SMilanka Ringwald 				cptr->effect = EFFECT_ARPEGGIO;
6338201da88SMatthias Ringwald 				cptr->parameffect = effect_param;
634a4cd9b30SMilanka Ringwald 
635a4cd9b30SMilanka Ringwald 				cptr->ArpIndex = 0;
636a4cd9b30SMilanka Ringwald 
6378201da88SMatthias Ringwald 				curnote = getnote(mod,cptr->period);
638a4cd9b30SMilanka Ringwald 
639a4cd9b30SMilanka Ringwald 				cptr->Arpperiods[0] = cptr->period;
640a4cd9b30SMilanka Ringwald 
6418201da88SMatthias Ringwald 				period_table_ptr = periodtable_finetune_ptr[cptr->finetune&0xF];
642a4cd9b30SMilanka Ringwald 
6438201da88SMatthias Ringwald 				arpnote = curnote + (((cptr->parameffect>>4)&0xF));
6448201da88SMatthias Ringwald 				if( arpnote >= MAXNOTES )
6458201da88SMatthias Ringwald 					arpnote = (MAXNOTES) - 1;
646a4cd9b30SMilanka Ringwald 
6478201da88SMatthias Ringwald 				cptr->Arpperiods[1] = period_table_ptr[arpnote];
648a4cd9b30SMilanka Ringwald 
6498201da88SMatthias Ringwald 				arpnote = curnote + (((cptr->parameffect)&0xF));
6508201da88SMatthias Ringwald 				if( arpnote >= MAXNOTES )
6518201da88SMatthias Ringwald 					arpnote = (MAXNOTES) - 1;
6528201da88SMatthias Ringwald 
6538201da88SMatthias Ringwald 				cptr->Arpperiods[2] = period_table_ptr[arpnote];
654a4cd9b30SMilanka Ringwald 			}
655a4cd9b30SMilanka Ringwald 		break;
656a4cd9b30SMilanka Ringwald 
657a4cd9b30SMilanka Ringwald 		case EFFECT_PORTAMENTO_UP:
658a4cd9b30SMilanka Ringwald 			/*
659a4cd9b30SMilanka Ringwald 			[1]: Slide up
660a4cd9b30SMilanka Ringwald 			Where [1][x][y] means "smoothly decrease the period of current
661a4cd9b30SMilanka Ringwald 			sample by x*16+y after each tick in the division". The
662a4cd9b30SMilanka Ringwald 			ticks/division are set with the 'set speed' effect (see below). If
663a4cd9b30SMilanka Ringwald 			the period of the note being played is z, then the final period
664a4cd9b30SMilanka Ringwald 			will be z - (x*16 + y)*(ticks - 1). As the slide rate depends on
665a4cd9b30SMilanka Ringwald 			the speed, changing the speed will change the slide. You cannot
666a4cd9b30SMilanka Ringwald 			slide beyond the note B3 (period 113).
667a4cd9b30SMilanka Ringwald 			*/
668a4cd9b30SMilanka Ringwald 
669a4cd9b30SMilanka Ringwald 			cptr->effect = EFFECT_PORTAMENTO_UP;
6708201da88SMatthias Ringwald 			cptr->parameffect = effect_param;
671a4cd9b30SMilanka Ringwald 		break;
672a4cd9b30SMilanka Ringwald 
673a4cd9b30SMilanka Ringwald 		case EFFECT_PORTAMENTO_DOWN:
674a4cd9b30SMilanka Ringwald 			/*
675a4cd9b30SMilanka Ringwald 			[2]: Slide down
676a4cd9b30SMilanka Ringwald 			Where [2][x][y] means "smoothly increase the period of current
677a4cd9b30SMilanka Ringwald 			sample by x*16+y after each tick in the division". Similar to [1],
678a4cd9b30SMilanka Ringwald 			but lowers the pitch. You cannot slide beyond the note C1 (period
679a4cd9b30SMilanka Ringwald 			856).
680a4cd9b30SMilanka Ringwald 			*/
681a4cd9b30SMilanka Ringwald 
682a4cd9b30SMilanka Ringwald 			cptr->effect = EFFECT_PORTAMENTO_DOWN;
6838201da88SMatthias Ringwald 			cptr->parameffect = effect_param;
684a4cd9b30SMilanka Ringwald 		break;
685a4cd9b30SMilanka Ringwald 
686a4cd9b30SMilanka Ringwald 		case EFFECT_TONE_PORTAMENTO:
687a4cd9b30SMilanka Ringwald 			/*
688a4cd9b30SMilanka Ringwald 			[3]: Slide to note
689a4cd9b30SMilanka Ringwald 			Where [3][x][y] means "smoothly change the period of current sample
690a4cd9b30SMilanka Ringwald 			by x*16+y after each tick in the division, never sliding beyond
691a4cd9b30SMilanka Ringwald 			current period". The period-length in this channel's division is a
692a4cd9b30SMilanka Ringwald 			parameter to this effect, and hence is not played. Sliding to a
693a4cd9b30SMilanka Ringwald 			note is similar to effects [1] and [2], but the slide will not go
694a4cd9b30SMilanka Ringwald 			beyond the given period, and the direction is implied by that
695a4cd9b30SMilanka Ringwald 			period. If x and y are both 0, then the old slide will continue.
696a4cd9b30SMilanka Ringwald 			*/
697a4cd9b30SMilanka Ringwald 
698a4cd9b30SMilanka Ringwald 			cptr->effect = EFFECT_TONE_PORTAMENTO;
6998201da88SMatthias Ringwald 			if( effect_param != 0 )
700a4cd9b30SMilanka Ringwald 			{
7018201da88SMatthias Ringwald 				cptr->portaspeed = (short)( effect_param );
702a4cd9b30SMilanka Ringwald 			}
703a4cd9b30SMilanka Ringwald 
704a4cd9b30SMilanka Ringwald 			if(period!=0)
705a4cd9b30SMilanka Ringwald 			{
706a4cd9b30SMilanka Ringwald 				cptr->portaperiod = period;
707a4cd9b30SMilanka Ringwald 				cptr->period = operiod;
708a4cd9b30SMilanka Ringwald 			}
709a4cd9b30SMilanka Ringwald 		break;
710a4cd9b30SMilanka Ringwald 
711a4cd9b30SMilanka Ringwald 		case EFFECT_VIBRATO:
712a4cd9b30SMilanka Ringwald 			/*
713a4cd9b30SMilanka Ringwald 			[4]: Vibrato
714a4cd9b30SMilanka Ringwald 			Where [4][x][y] means "oscillate the sample pitch using a
715a4cd9b30SMilanka Ringwald 			particular waveform with amplitude y/16 semitones, such that (x *
716a4cd9b30SMilanka Ringwald 			ticks)/64 cycles occur in the division". The waveform is set using
717a4cd9b30SMilanka Ringwald 			effect [14][4]. By placing vibrato effects on consecutive
718a4cd9b30SMilanka Ringwald 			divisions, the vibrato effect can be maintained. If either x or y
719a4cd9b30SMilanka Ringwald 			are 0, then the old vibrato values will be used.
720a4cd9b30SMilanka Ringwald 			*/
721a4cd9b30SMilanka Ringwald 
722a4cd9b30SMilanka Ringwald 			cptr->effect = EFFECT_VIBRATO;
7238201da88SMatthias Ringwald 			if( effect_param_l != 0 ) // Depth continue or change ?
7248201da88SMatthias Ringwald 				cptr->vibraparam = ( cptr->vibraparam & 0xF0 ) | effect_param_l;
7258201da88SMatthias Ringwald 			if( effect_param_h != 0 ) // Speed continue or change ?
7268201da88SMatthias Ringwald 				cptr->vibraparam = ( cptr->vibraparam & 0x0F ) | ( effect_param_h << 4 );
727a4cd9b30SMilanka Ringwald 
728a4cd9b30SMilanka Ringwald 		break;
729a4cd9b30SMilanka Ringwald 
730a4cd9b30SMilanka Ringwald 		case EFFECT_VOLSLIDE_TONEPORTA:
731a4cd9b30SMilanka Ringwald 			/*
732a4cd9b30SMilanka Ringwald 			[5]: Continue 'Slide to note', but also do Volume slide
733a4cd9b30SMilanka Ringwald 			Where [5][x][y] means "either slide the volume up x*(ticks - 1) or
734a4cd9b30SMilanka Ringwald 			slide the volume down y*(ticks - 1), at the same time as continuing
735a4cd9b30SMilanka Ringwald 			the last 'Slide to note'". It is illegal for both x and y to be
736a4cd9b30SMilanka Ringwald 			non-zero. You cannot slide outside the volume range 0..64. The
737a4cd9b30SMilanka Ringwald 			period-length in this channel's division is a parameter to this
738a4cd9b30SMilanka Ringwald 			effect, and hence is not played.
739a4cd9b30SMilanka Ringwald 			*/
740a4cd9b30SMilanka Ringwald 
741a4cd9b30SMilanka Ringwald 			if( period != 0 )
742a4cd9b30SMilanka Ringwald 			{
743a4cd9b30SMilanka Ringwald 				cptr->portaperiod = period;
744a4cd9b30SMilanka Ringwald 				cptr->period = operiod;
745a4cd9b30SMilanka Ringwald 			}
746a4cd9b30SMilanka Ringwald 
747a4cd9b30SMilanka Ringwald 			cptr->effect = EFFECT_VOLSLIDE_TONEPORTA;
7488201da88SMatthias Ringwald 			if( effect_param != 0 )
7498201da88SMatthias Ringwald 				cptr->volumeslide = effect_param;
750a4cd9b30SMilanka Ringwald 
751a4cd9b30SMilanka Ringwald 		break;
752a4cd9b30SMilanka Ringwald 
753a4cd9b30SMilanka Ringwald 		case EFFECT_VOLSLIDE_VIBRATO:
754a4cd9b30SMilanka Ringwald 			/*
755a4cd9b30SMilanka Ringwald 			[6]: Continue 'Vibrato', but also do Volume slide
756a4cd9b30SMilanka Ringwald 			Where [6][x][y] means "either slide the volume up x*(ticks - 1) or
757a4cd9b30SMilanka Ringwald 			slide the volume down y*(ticks - 1), at the same time as continuing
758a4cd9b30SMilanka Ringwald 			the last 'Vibrato'". It is illegal for both x and y to be non-zero.
759a4cd9b30SMilanka Ringwald 			You cannot slide outside the volume range 0..64.
760a4cd9b30SMilanka Ringwald 			*/
761a4cd9b30SMilanka Ringwald 
762a4cd9b30SMilanka Ringwald 			cptr->effect = EFFECT_VOLSLIDE_VIBRATO;
7638201da88SMatthias Ringwald 			if( effect_param != 0 )
7648201da88SMatthias Ringwald 				cptr->volumeslide = effect_param;
765a4cd9b30SMilanka Ringwald 		break;
766a4cd9b30SMilanka Ringwald 
767a4cd9b30SMilanka Ringwald 		case EFFECT_SET_OFFSET:
768a4cd9b30SMilanka Ringwald 			/*
769a4cd9b30SMilanka Ringwald 			[9]: Set sample offset
770a4cd9b30SMilanka Ringwald 			Where [9][x][y] means "play the sample from offset x*4096 + y*256".
771a4cd9b30SMilanka Ringwald 			The offset is measured in words. If no sample is given, yet one is
772a4cd9b30SMilanka Ringwald 			still playing on this channel, it should be retriggered to the new
773a4cd9b30SMilanka Ringwald 			offset using the current volume.
7748201da88SMatthias Ringwald 			If xy is 00, the previous value is used.
775a4cd9b30SMilanka Ringwald 			*/
776a4cd9b30SMilanka Ringwald 
7778201da88SMatthias Ringwald 			cptr->samppos = ( ( ((muint)effect_param_h) << 12) + ( (((muint)effect_param_l) << 8) ) ) << 10;
778a4cd9b30SMilanka Ringwald 
7798201da88SMatthias Ringwald 			if(!cptr->samppos)
7808201da88SMatthias Ringwald 				cptr->samppos = cptr->last_set_offset;
7818201da88SMatthias Ringwald 
7828201da88SMatthias Ringwald 			cptr->last_set_offset = cptr->samppos;
783a4cd9b30SMilanka Ringwald 		break;
784a4cd9b30SMilanka Ringwald 
785a4cd9b30SMilanka Ringwald 		case EFFECT_VOLUME_SLIDE:
786a4cd9b30SMilanka Ringwald 			/*
787a4cd9b30SMilanka Ringwald 			[10]: Volume slide
788a4cd9b30SMilanka Ringwald 			Where [10][x][y] means "either slide the volume up x*(ticks - 1) or
789a4cd9b30SMilanka Ringwald 			slide the volume down y*(ticks - 1)". If both x and y are non-zero,
790a4cd9b30SMilanka Ringwald 			then the y value is ignored (assumed to be 0). You cannot slide
791a4cd9b30SMilanka Ringwald 			outside the volume range 0..64.
792a4cd9b30SMilanka Ringwald 			*/
793a4cd9b30SMilanka Ringwald 
794a4cd9b30SMilanka Ringwald 			cptr->effect = EFFECT_VOLUME_SLIDE;
7958201da88SMatthias Ringwald 			cptr->volumeslide = effect_param;
796a4cd9b30SMilanka Ringwald 		break;
797a4cd9b30SMilanka Ringwald 
798a4cd9b30SMilanka Ringwald 		case EFFECT_JUMP_POSITION:
799a4cd9b30SMilanka Ringwald 			/*
800a4cd9b30SMilanka Ringwald 			[11]: Position Jump
801a4cd9b30SMilanka Ringwald 			Where [11][x][y] means "stop the pattern after this division, and
802a4cd9b30SMilanka Ringwald 			continue the song at song-position x*16+y". This shifts the
803a4cd9b30SMilanka Ringwald 			'pattern-cursor' in the pattern table (see above). Legal values for
804a4cd9b30SMilanka Ringwald 			x*16+y are from 0 to 127.
805a4cd9b30SMilanka Ringwald 			*/
806a4cd9b30SMilanka Ringwald 
8078201da88SMatthias Ringwald 			mod->tablepos = effect_param;
808a4cd9b30SMilanka Ringwald 			if(mod->tablepos >= mod->song.length)
809a4cd9b30SMilanka Ringwald 				mod->tablepos = 0;
810a4cd9b30SMilanka Ringwald 			mod->patternpos = 0;
811a4cd9b30SMilanka Ringwald 			mod->jump_loop_effect = 1;
812a4cd9b30SMilanka Ringwald 
813a4cd9b30SMilanka Ringwald 		break;
814a4cd9b30SMilanka Ringwald 
815a4cd9b30SMilanka Ringwald 		case EFFECT_SET_VOLUME:
816a4cd9b30SMilanka Ringwald 			/*
817a4cd9b30SMilanka Ringwald 			[12]: Set volume
818a4cd9b30SMilanka Ringwald 			Where [12][x][y] means "set current sample's volume to x*16+y".
819a4cd9b30SMilanka Ringwald 			Legal volumes are 0..64.
820a4cd9b30SMilanka Ringwald 			*/
821a4cd9b30SMilanka Ringwald 
8228201da88SMatthias Ringwald 			cptr->volume = effect_param;
8238201da88SMatthias Ringwald 
8248201da88SMatthias Ringwald 			if(cptr->volume > 64)
8258201da88SMatthias Ringwald 				cptr->volume = 64;
8268201da88SMatthias Ringwald 
8278201da88SMatthias Ringwald #ifdef HXCMOD_USE_PRECALC_VOLUME_TABLE
8288201da88SMatthias Ringwald 			cptr->volume_table = mod->volume_selection_table[cptr->volume];
8298201da88SMatthias Ringwald #endif
830a4cd9b30SMilanka Ringwald 		break;
831a4cd9b30SMilanka Ringwald 
832a4cd9b30SMilanka Ringwald 		case EFFECT_PATTERN_BREAK:
833a4cd9b30SMilanka Ringwald 			/*
834a4cd9b30SMilanka Ringwald 			[13]: Pattern Break
835a4cd9b30SMilanka Ringwald 			Where [13][x][y] means "stop the pattern after this division, and
836a4cd9b30SMilanka Ringwald 			continue the song at the next pattern at division x*10+y" (the 10
837a4cd9b30SMilanka Ringwald 			is not a typo). Legal divisions are from 0 to 63 (note Protracker
838a4cd9b30SMilanka Ringwald 			exception above).
839a4cd9b30SMilanka Ringwald 			*/
840a4cd9b30SMilanka Ringwald 
8418201da88SMatthias Ringwald 			mod->patternpos = ( ((muint)(effect_param_h) * 10) + effect_param_l );
8428201da88SMatthias Ringwald 
8438201da88SMatthias Ringwald 			if(mod->patternpos >= 64)
8448201da88SMatthias Ringwald 				mod->patternpos = 63;
8458201da88SMatthias Ringwald 
8468201da88SMatthias Ringwald 			mod->patternpos *= mod->number_of_channels;
8478201da88SMatthias Ringwald 
8488201da88SMatthias Ringwald 			if(!mod->jump_loop_effect)
8498201da88SMatthias Ringwald 			{
850a4cd9b30SMilanka Ringwald 				mod->tablepos++;
851a4cd9b30SMilanka Ringwald 				if(mod->tablepos >= mod->song.length)
852a4cd9b30SMilanka Ringwald 					mod->tablepos = 0;
8538201da88SMatthias Ringwald 			}
854a4cd9b30SMilanka Ringwald 
8558201da88SMatthias Ringwald 			mod->jump_loop_effect = 1;
856a4cd9b30SMilanka Ringwald 		break;
857a4cd9b30SMilanka Ringwald 
858a4cd9b30SMilanka Ringwald 		case EFFECT_EXTENDED:
8598201da88SMatthias Ringwald 			switch( effect_param_h )
860a4cd9b30SMilanka Ringwald 			{
861a4cd9b30SMilanka Ringwald 				case EFFECT_E_FINE_PORTA_UP:
862a4cd9b30SMilanka Ringwald 					/*
863a4cd9b30SMilanka Ringwald 					[14][1]: Fineslide up
864a4cd9b30SMilanka Ringwald 					Where [14][1][x] means "decrement the period of the current sample
865a4cd9b30SMilanka Ringwald 					by x". The incrementing takes place at the beginning of the
866a4cd9b30SMilanka Ringwald 					division, and hence there is no actual sliding. You cannot slide
867a4cd9b30SMilanka Ringwald 					beyond the note B3 (period 113).
868a4cd9b30SMilanka Ringwald 					*/
869a4cd9b30SMilanka Ringwald 
8708201da88SMatthias Ringwald 					cptr->period -= effect_param_l;
871a4cd9b30SMilanka Ringwald 					if( cptr->period < 113 )
872a4cd9b30SMilanka Ringwald 						cptr->period = 113;
873a4cd9b30SMilanka Ringwald 				break;
874a4cd9b30SMilanka Ringwald 
875a4cd9b30SMilanka Ringwald 				case EFFECT_E_FINE_PORTA_DOWN:
876a4cd9b30SMilanka Ringwald 					/*
877a4cd9b30SMilanka Ringwald 					[14][2]: Fineslide down
878a4cd9b30SMilanka Ringwald 					Where [14][2][x] means "increment the period of the current sample
879a4cd9b30SMilanka Ringwald 					by x". Similar to [14][1] but shifts the pitch down. You cannot
880a4cd9b30SMilanka Ringwald 					slide beyond the note C1 (period 856).
881a4cd9b30SMilanka Ringwald 					*/
882a4cd9b30SMilanka Ringwald 
8838201da88SMatthias Ringwald 					cptr->period += effect_param_l;
884a4cd9b30SMilanka Ringwald 					if( cptr->period > 856 )
885a4cd9b30SMilanka Ringwald 						cptr->period = 856;
886a4cd9b30SMilanka Ringwald 				break;
887a4cd9b30SMilanka Ringwald 
8888201da88SMatthias Ringwald 				case EFFECT_E_GLISSANDO_CTRL:
8898201da88SMatthias Ringwald 					/*
8908201da88SMatthias Ringwald 					[14][3]: Set glissando on/off
8918201da88SMatthias Ringwald 					Where [14][3][x] means "set glissando ON if x is 1, OFF if x is 0".
8928201da88SMatthias Ringwald 					Used in conjunction with [3] ('Slide to note'). If glissando is on,
8938201da88SMatthias Ringwald 					then 'Slide to note' will slide in semitones, otherwise will
8948201da88SMatthias Ringwald 					perform the default smooth slide.
8958201da88SMatthias Ringwald 					*/
8968201da88SMatthias Ringwald 
8978201da88SMatthias Ringwald 					cptr->glissando = effect_param_l;
8988201da88SMatthias Ringwald 				break;
8998201da88SMatthias Ringwald 
900a4cd9b30SMilanka Ringwald 				case EFFECT_E_FINE_VOLSLIDE_UP:
901a4cd9b30SMilanka Ringwald 					/*
902a4cd9b30SMilanka Ringwald 					[14][10]: Fine volume slide up
903a4cd9b30SMilanka Ringwald 					Where [14][10][x] means "increment the volume of the current sample
904a4cd9b30SMilanka Ringwald 					by x". The incrementing takes place at the beginning of the
905a4cd9b30SMilanka Ringwald 					division, and hence there is no sliding. You cannot slide beyond
906a4cd9b30SMilanka Ringwald 					volume 64.
907a4cd9b30SMilanka Ringwald 					*/
908a4cd9b30SMilanka Ringwald 
9098201da88SMatthias Ringwald 					cptr->volume += effect_param_l;
910a4cd9b30SMilanka Ringwald 					if( cptr->volume > 64 )
911a4cd9b30SMilanka Ringwald 						cptr->volume = 64;
9128201da88SMatthias Ringwald #ifdef HXCMOD_USE_PRECALC_VOLUME_TABLE
9138201da88SMatthias Ringwald 					cptr->volume_table = mod->volume_selection_table[cptr->volume];
9148201da88SMatthias Ringwald #endif
915a4cd9b30SMilanka Ringwald 				break;
916a4cd9b30SMilanka Ringwald 
917a4cd9b30SMilanka Ringwald 				case EFFECT_E_FINE_VOLSLIDE_DOWN:
918a4cd9b30SMilanka Ringwald 					/*
919a4cd9b30SMilanka Ringwald 					[14][11]: Fine volume slide down
920a4cd9b30SMilanka Ringwald 					Where [14][11][x] means "decrement the volume of the current sample
921a4cd9b30SMilanka Ringwald 					by x". Similar to [14][10] but lowers volume. You cannot slide
922a4cd9b30SMilanka Ringwald 					beyond volume 0.
923a4cd9b30SMilanka Ringwald 					*/
924a4cd9b30SMilanka Ringwald 
9258201da88SMatthias Ringwald 					cptr->volume -= effect_param_l;
926a4cd9b30SMilanka Ringwald 					if( cptr->volume > 200 )
927a4cd9b30SMilanka Ringwald 						cptr->volume = 0;
9288201da88SMatthias Ringwald #ifdef HXCMOD_USE_PRECALC_VOLUME_TABLE
9298201da88SMatthias Ringwald 					cptr->volume_table = mod->volume_selection_table[cptr->volume];
9308201da88SMatthias Ringwald #endif
9318201da88SMatthias Ringwald 				break;
9328201da88SMatthias Ringwald 
9338201da88SMatthias Ringwald 				case EFFECT_E_SET_FINETUNE:
9348201da88SMatthias Ringwald 					/*
9358201da88SMatthias Ringwald 					[14][5]: Set finetune value
9368201da88SMatthias Ringwald 					Where [14][5][x] means "sets the finetune value of the current
9378201da88SMatthias Ringwald 					sample to the signed nibble x". x has legal values of 0..15,
9388201da88SMatthias Ringwald 					corresponding to signed nibbles 0..7,-8..-1 (see start of text for
9398201da88SMatthias Ringwald 					more info on finetune values).
9408201da88SMatthias Ringwald 					*/
9418201da88SMatthias Ringwald 
9428201da88SMatthias Ringwald 					cptr->finetune = effect_param_l;
9438201da88SMatthias Ringwald 
9448201da88SMatthias Ringwald 					if( period )
9458201da88SMatthias Ringwald 					{
9468201da88SMatthias Ringwald 						period_table_ptr = periodtable_finetune_ptr[cptr->finetune&0xF];
9478201da88SMatthias Ringwald 						period = period_table_ptr[getnote(mod,period)];
9488201da88SMatthias Ringwald 						cptr->period = period;
9498201da88SMatthias Ringwald 					}
9508201da88SMatthias Ringwald 
951a4cd9b30SMilanka Ringwald 				break;
952a4cd9b30SMilanka Ringwald 
953a4cd9b30SMilanka Ringwald 				case EFFECT_E_PATTERN_LOOP:
954a4cd9b30SMilanka Ringwald 					/*
955a4cd9b30SMilanka Ringwald 					[14][6]: Loop pattern
956a4cd9b30SMilanka Ringwald 					Where [14][6][x] means "set the start of a loop to this division if
957a4cd9b30SMilanka Ringwald 					x is 0, otherwise after this division, jump back to the start of a
958a4cd9b30SMilanka Ringwald 					loop and play it another x times before continuing". If the start
959a4cd9b30SMilanka Ringwald 					of the loop was not set, it will default to the start of the
960a4cd9b30SMilanka Ringwald 					current pattern. Hence 'loop pattern' cannot be performed across
961a4cd9b30SMilanka Ringwald 					multiple patterns. Note that loops do not support nesting, and you
962a4cd9b30SMilanka Ringwald 					may generate an infinite loop if you try to nest 'loop pattern's.
963a4cd9b30SMilanka Ringwald 					*/
964a4cd9b30SMilanka Ringwald 
9658201da88SMatthias Ringwald 					if( effect_param_l )
966a4cd9b30SMilanka Ringwald 					{
967a4cd9b30SMilanka Ringwald 						if( cptr->patternloopcnt )
968a4cd9b30SMilanka Ringwald 						{
969a4cd9b30SMilanka Ringwald 							cptr->patternloopcnt--;
970a4cd9b30SMilanka Ringwald 							if( cptr->patternloopcnt )
971a4cd9b30SMilanka Ringwald 							{
972a4cd9b30SMilanka Ringwald 								mod->patternpos = cptr->patternloopstartpoint;
973a4cd9b30SMilanka Ringwald 								mod->jump_loop_effect = 1;
974a4cd9b30SMilanka Ringwald 							}
975a4cd9b30SMilanka Ringwald 							else
976a4cd9b30SMilanka Ringwald 							{
977a4cd9b30SMilanka Ringwald 								cptr->patternloopstartpoint = mod->patternpos ;
978a4cd9b30SMilanka Ringwald 							}
979a4cd9b30SMilanka Ringwald 						}
980a4cd9b30SMilanka Ringwald 						else
981a4cd9b30SMilanka Ringwald 						{
9828201da88SMatthias Ringwald 							cptr->patternloopcnt = effect_param_l;
983a4cd9b30SMilanka Ringwald 							mod->patternpos = cptr->patternloopstartpoint;
984a4cd9b30SMilanka Ringwald 							mod->jump_loop_effect = 1;
985a4cd9b30SMilanka Ringwald 						}
986a4cd9b30SMilanka Ringwald 					}
987a4cd9b30SMilanka Ringwald 					else // Start point
988a4cd9b30SMilanka Ringwald 					{
989a4cd9b30SMilanka Ringwald 						cptr->patternloopstartpoint = mod->patternpos;
990a4cd9b30SMilanka Ringwald 					}
991a4cd9b30SMilanka Ringwald 
992a4cd9b30SMilanka Ringwald 				break;
993a4cd9b30SMilanka Ringwald 
994a4cd9b30SMilanka Ringwald 				case EFFECT_E_PATTERN_DELAY:
995a4cd9b30SMilanka Ringwald 					/*
996a4cd9b30SMilanka Ringwald 					[14][14]: Delay pattern
997a4cd9b30SMilanka Ringwald 					Where [14][14][x] means "after this division there will be a delay
998a4cd9b30SMilanka Ringwald 					equivalent to the time taken to play x divisions after which the
999a4cd9b30SMilanka Ringwald 					pattern will be resumed". The delay only relates to the
1000a4cd9b30SMilanka Ringwald 					interpreting of new divisions, and all effects and previous notes
1001a4cd9b30SMilanka Ringwald 					continue during delay.
1002a4cd9b30SMilanka Ringwald 					*/
1003a4cd9b30SMilanka Ringwald 
10048201da88SMatthias Ringwald 					mod->patterndelay = effect_param_l;
10058201da88SMatthias Ringwald 				break;
10068201da88SMatthias Ringwald 
10078201da88SMatthias Ringwald 				case EFFECT_E_RETRIGGER_NOTE:
10088201da88SMatthias Ringwald 					/*
10098201da88SMatthias Ringwald 					[14][9]: Retrigger sample
10108201da88SMatthias Ringwald 					 Where [14][9][x] means "trigger current sample every x ticks in
10118201da88SMatthias Ringwald 					 this division". If x is 0, then no retriggering is done (acts as if
10128201da88SMatthias Ringwald 					 no effect was chosen), otherwise the retriggering begins on the
10138201da88SMatthias Ringwald 					 first tick and then x ticks after that, etc.
10148201da88SMatthias Ringwald 					*/
10158201da88SMatthias Ringwald 
10168201da88SMatthias Ringwald 					if( effect_param_l )
10178201da88SMatthias Ringwald 					{
10188201da88SMatthias Ringwald 						cptr->effect = EFFECT_EXTENDED;
10198201da88SMatthias Ringwald 						cptr->parameffect = (EFFECT_E_RETRIGGER_NOTE<<4);
10208201da88SMatthias Ringwald 						cptr->retrig_param = effect_param_l;
10218201da88SMatthias Ringwald 						cptr->retrig_cnt = 0;
10228201da88SMatthias Ringwald 					}
1023a4cd9b30SMilanka Ringwald 				break;
1024a4cd9b30SMilanka Ringwald 
1025a4cd9b30SMilanka Ringwald 				case EFFECT_E_NOTE_CUT:
1026a4cd9b30SMilanka Ringwald 					/*
1027a4cd9b30SMilanka Ringwald 					[14][12]: Cut sample
1028a4cd9b30SMilanka Ringwald 					Where [14][12][x] means "after the current sample has been played
1029a4cd9b30SMilanka Ringwald 					for x ticks in this division, its volume will be set to 0". This
1030a4cd9b30SMilanka Ringwald 					implies that if x is 0, then you will not hear any of the sample.
1031a4cd9b30SMilanka Ringwald 					If you wish to insert "silence" in a pattern, it is better to use a
1032a4cd9b30SMilanka Ringwald 					"silence"-sample (see above) due to the lack of proper support for
1033a4cd9b30SMilanka Ringwald 					this effect.
1034a4cd9b30SMilanka Ringwald 					*/
10358201da88SMatthias Ringwald 
1036a4cd9b30SMilanka Ringwald 					cptr->effect = EFFECT_E_NOTE_CUT;
10378201da88SMatthias Ringwald 					cptr->cut_param = effect_param_l;
1038a4cd9b30SMilanka Ringwald 					if( !cptr->cut_param )
10398201da88SMatthias Ringwald 					{
1040a4cd9b30SMilanka Ringwald 						cptr->volume = 0;
10418201da88SMatthias Ringwald #ifdef HXCMOD_USE_PRECALC_VOLUME_TABLE
10428201da88SMatthias Ringwald 						cptr->volume_table = mod->volume_selection_table[cptr->volume];
10438201da88SMatthias Ringwald #endif
10448201da88SMatthias Ringwald 					}
10458201da88SMatthias Ringwald 				break;
10468201da88SMatthias Ringwald 
10478201da88SMatthias Ringwald 				case EFFECT_E_NOTE_DELAY:
10488201da88SMatthias Ringwald 					/*
10498201da88SMatthias Ringwald 					 Where [14][13][x] means "do not start this division's sample for
10508201da88SMatthias Ringwald 					 the first x ticks in this division, play the sample after this".
10518201da88SMatthias Ringwald 					 This implies that if x is 0, then you will hear no delay, but
10528201da88SMatthias Ringwald 					 actually there will be a VERY small delay. Note that this effect
10538201da88SMatthias Ringwald 					 only influences a sample if it was started in this division.
10548201da88SMatthias Ringwald 					*/
10558201da88SMatthias Ringwald 
10568201da88SMatthias Ringwald 					cptr->effect = EFFECT_EXTENDED;
10578201da88SMatthias Ringwald 					cptr->parameffect = (EFFECT_E_NOTE_DELAY<<4);
10588201da88SMatthias Ringwald 				break;
10598201da88SMatthias Ringwald 
10608201da88SMatthias Ringwald 				case EFFECT_E_INVERT_LOOP:
10618201da88SMatthias Ringwald 					/*
10628201da88SMatthias Ringwald 					Where [14][15][x] means "if x is greater than 0, then play the
10638201da88SMatthias Ringwald 					current sample's loop upside down at speed x". Each byte in the
10648201da88SMatthias Ringwald 					sample's loop will have its sign changed (negated). It will only
10658201da88SMatthias Ringwald 					work if the sample's loop (defined previously) is not too big. The
10668201da88SMatthias Ringwald 					speed is based on an internal table.
10678201da88SMatthias Ringwald 					*/
10688201da88SMatthias Ringwald 
10698201da88SMatthias Ringwald 					cptr->funkspeed = effect_param_l;
10708201da88SMatthias Ringwald 
10718201da88SMatthias Ringwald 					doFunk(cptr);
10728201da88SMatthias Ringwald 
1073a4cd9b30SMilanka Ringwald 				break;
1074a4cd9b30SMilanka Ringwald 
1075a4cd9b30SMilanka Ringwald 				default:
1076a4cd9b30SMilanka Ringwald 
1077a4cd9b30SMilanka Ringwald 				break;
1078a4cd9b30SMilanka Ringwald 			}
1079a4cd9b30SMilanka Ringwald 		break;
1080a4cd9b30SMilanka Ringwald 
1081a4cd9b30SMilanka Ringwald 		case 0xF:
1082a4cd9b30SMilanka Ringwald 			/*
1083a4cd9b30SMilanka Ringwald 			[15]: Set speed
1084a4cd9b30SMilanka Ringwald 			Where [15][x][y] means "set speed to x*16+y". Though it is nowhere
1085a4cd9b30SMilanka Ringwald 			near that simple. Let z = x*16+y. Depending on what values z takes,
1086a4cd9b30SMilanka Ringwald 			different units of speed are set, there being two: ticks/division
1087a4cd9b30SMilanka Ringwald 			and beats/minute (though this one is only a label and not strictly
1088a4cd9b30SMilanka Ringwald 			true). If z=0, then what should technically happen is that the
1089a4cd9b30SMilanka Ringwald 			module stops, but in practice it is treated as if z=1, because
1090a4cd9b30SMilanka Ringwald 			there is already a method for stopping the module (running out of
1091a4cd9b30SMilanka Ringwald 			patterns). If z<=32, then it means "set ticks/division to z"
1092a4cd9b30SMilanka Ringwald 			otherwise it means "set beats/minute to z" (convention says that
1093a4cd9b30SMilanka Ringwald 			this should read "If z<32.." but there are some composers out there
1094a4cd9b30SMilanka Ringwald 			that defy conventions). Default values are 6 ticks/division, and
1095a4cd9b30SMilanka Ringwald 			125 beats/minute (4 divisions = 1 beat). The beats/minute tag is
1096a4cd9b30SMilanka Ringwald 			only meaningful for 6 ticks/division. To get a more accurate view
1097a4cd9b30SMilanka Ringwald 			of how things work, use the following formula:
1098a4cd9b30SMilanka Ringwald 									 24 * beats/minute
1099a4cd9b30SMilanka Ringwald 				  divisions/minute = -----------------
1100a4cd9b30SMilanka Ringwald 									  ticks/division
1101a4cd9b30SMilanka Ringwald 			Hence divisions/minute range from 24.75 to 6120, eg. to get a value
1102a4cd9b30SMilanka Ringwald 			of 2000 divisions/minute use 3 ticks/division and 250 beats/minute.
1103a4cd9b30SMilanka Ringwald 			If multiple "set speed" effects are performed in a single division,
1104a4cd9b30SMilanka Ringwald 			the ones on higher-numbered channels take precedence over the ones
1105a4cd9b30SMilanka Ringwald 			on lower-numbered channels. This effect has a large number of
1106a4cd9b30SMilanka Ringwald 			different implementations, but the one described here has the
1107a4cd9b30SMilanka Ringwald 			widest usage.
1108a4cd9b30SMilanka Ringwald 			*/
1109a4cd9b30SMilanka Ringwald 
11108201da88SMatthias Ringwald 
11118201da88SMatthias Ringwald 			if( effect_param )
1112a4cd9b30SMilanka Ringwald 			{
11138201da88SMatthias Ringwald 
11148201da88SMatthias Ringwald 				if( effect_param < 0x20 )
1115a4cd9b30SMilanka Ringwald 				{
11168201da88SMatthias Ringwald 					mod->song.speed = effect_param;
1117a4cd9b30SMilanka Ringwald 				}
11188201da88SMatthias Ringwald 				else
11198201da88SMatthias Ringwald 				{   // effect_param >= 0x20
11208201da88SMatthias Ringwald 					///	 HZ = 2 * BPM / 5
11218201da88SMatthias Ringwald 					mod->bpm = effect_param;
1122a4cd9b30SMilanka Ringwald 				}
1123a4cd9b30SMilanka Ringwald 
11248201da88SMatthias Ringwald #ifdef HXCMOD_16BITS_TARGET
11258201da88SMatthias Ringwald 				// song.speed = 1 <> 31
11268201da88SMatthias Ringwald 				// playrate = 8000 <> 22050
11278201da88SMatthias Ringwald 				// bpm = 32 <> 255
11288201da88SMatthias Ringwald 
11298201da88SMatthias Ringwald 				mod->patternticksem = (muint)( ( (mulong)mod->playrate * 5 ) / ( (muint)mod->bpm * 2 ) );
11308201da88SMatthias Ringwald #else
11318201da88SMatthias Ringwald 				// song.speed = 1 <> 31
11328201da88SMatthias Ringwald 				// playrate = 8000 <> 96000
11338201da88SMatthias Ringwald 				// bpm = 32 <> 255
11348201da88SMatthias Ringwald 
11358201da88SMatthias Ringwald 				mod->patternticksem = ( ( mod->playrate * 5 ) / ( (mulong)mod->bpm * 2 ) );
11368201da88SMatthias Ringwald #endif
11378201da88SMatthias Ringwald 				mod->patternticksaim = mod->song.speed * mod->patternticksem;
1138a4cd9b30SMilanka Ringwald 			}
1139a4cd9b30SMilanka Ringwald 
1140a4cd9b30SMilanka Ringwald 		break;
1141a4cd9b30SMilanka Ringwald 
1142a4cd9b30SMilanka Ringwald 		default:
1143a4cd9b30SMilanka Ringwald 		// Unsupported effect
1144a4cd9b30SMilanka Ringwald 		break;
1145a4cd9b30SMilanka Ringwald 
1146a4cd9b30SMilanka Ringwald 	}
1147a4cd9b30SMilanka Ringwald 
1148a4cd9b30SMilanka Ringwald }
1149a4cd9b30SMilanka Ringwald 
11508201da88SMatthias Ringwald static void workeffect( modcontext * modctx, note * nptr, channel * cptr )
1151a4cd9b30SMilanka Ringwald {
1152*4aa7d471SMatthias Ringwald 	// BK4BSTACK_CHANGE START
1153*4aa7d471SMatthias Ringwald 	(void) nptr;
1154*4aa7d471SMatthias Ringwald 	// BK4BSTACK_CHANGE END
1155*4aa7d471SMatthias Ringwald 
11568201da88SMatthias Ringwald 	doFunk(cptr);
1157c5456c21SMilanka Ringwald 
1158a4cd9b30SMilanka Ringwald 	switch(cptr->effect)
1159a4cd9b30SMilanka Ringwald 	{
1160a4cd9b30SMilanka Ringwald 		case EFFECT_ARPEGGIO:
1161a4cd9b30SMilanka Ringwald 
1162a4cd9b30SMilanka Ringwald 			if( cptr->parameffect )
1163a4cd9b30SMilanka Ringwald 			{
1164a4cd9b30SMilanka Ringwald 				cptr->decalperiod = cptr->period - cptr->Arpperiods[cptr->ArpIndex];
1165a4cd9b30SMilanka Ringwald 
1166a4cd9b30SMilanka Ringwald 				cptr->ArpIndex++;
1167a4cd9b30SMilanka Ringwald 				if( cptr->ArpIndex>2 )
1168a4cd9b30SMilanka Ringwald 					cptr->ArpIndex = 0;
1169a4cd9b30SMilanka Ringwald 			}
1170a4cd9b30SMilanka Ringwald 		break;
1171a4cd9b30SMilanka Ringwald 
1172a4cd9b30SMilanka Ringwald 		case EFFECT_PORTAMENTO_UP:
1173a4cd9b30SMilanka Ringwald 
1174a4cd9b30SMilanka Ringwald 			if( cptr->period )
1175a4cd9b30SMilanka Ringwald 			{
1176a4cd9b30SMilanka Ringwald 				cptr->period -= cptr->parameffect;
1177a4cd9b30SMilanka Ringwald 
1178a4cd9b30SMilanka Ringwald 				if( cptr->period < 113 || cptr->period > 20000 )
1179a4cd9b30SMilanka Ringwald 					cptr->period = 113;
1180a4cd9b30SMilanka Ringwald 			}
1181a4cd9b30SMilanka Ringwald 
1182a4cd9b30SMilanka Ringwald 		break;
1183a4cd9b30SMilanka Ringwald 
1184a4cd9b30SMilanka Ringwald 		case EFFECT_PORTAMENTO_DOWN:
1185a4cd9b30SMilanka Ringwald 
1186a4cd9b30SMilanka Ringwald 			if( cptr->period )
1187a4cd9b30SMilanka Ringwald 			{
1188a4cd9b30SMilanka Ringwald 				cptr->period += cptr->parameffect;
1189a4cd9b30SMilanka Ringwald 
1190a4cd9b30SMilanka Ringwald 				if( cptr->period > 20000 )
1191a4cd9b30SMilanka Ringwald 					cptr->period = 20000;
1192a4cd9b30SMilanka Ringwald 			}
1193a4cd9b30SMilanka Ringwald 
1194a4cd9b30SMilanka Ringwald 		break;
1195a4cd9b30SMilanka Ringwald 
1196a4cd9b30SMilanka Ringwald 		case EFFECT_VOLSLIDE_TONEPORTA:
1197a4cd9b30SMilanka Ringwald 		case EFFECT_TONE_PORTAMENTO:
1198a4cd9b30SMilanka Ringwald 
1199a4cd9b30SMilanka Ringwald 			if( cptr->period && ( cptr->period != cptr->portaperiod ) && cptr->portaperiod )
1200a4cd9b30SMilanka Ringwald 			{
1201a4cd9b30SMilanka Ringwald 				if( cptr->period > cptr->portaperiod )
1202a4cd9b30SMilanka Ringwald 				{
1203a4cd9b30SMilanka Ringwald 					if( cptr->period - cptr->portaperiod >= cptr->portaspeed )
1204a4cd9b30SMilanka Ringwald 					{
1205a4cd9b30SMilanka Ringwald 						cptr->period -= cptr->portaspeed;
1206a4cd9b30SMilanka Ringwald 					}
1207a4cd9b30SMilanka Ringwald 					else
1208a4cd9b30SMilanka Ringwald 					{
1209a4cd9b30SMilanka Ringwald 						cptr->period = cptr->portaperiod;
1210a4cd9b30SMilanka Ringwald 					}
1211a4cd9b30SMilanka Ringwald 				}
1212a4cd9b30SMilanka Ringwald 				else
1213a4cd9b30SMilanka Ringwald 				{
1214a4cd9b30SMilanka Ringwald 					if( cptr->portaperiod - cptr->period >= cptr->portaspeed )
1215a4cd9b30SMilanka Ringwald 					{
1216a4cd9b30SMilanka Ringwald 						cptr->period += cptr->portaspeed;
1217a4cd9b30SMilanka Ringwald 					}
1218a4cd9b30SMilanka Ringwald 					else
1219a4cd9b30SMilanka Ringwald 					{
1220a4cd9b30SMilanka Ringwald 						cptr->period = cptr->portaperiod;
1221a4cd9b30SMilanka Ringwald 					}
1222a4cd9b30SMilanka Ringwald 				}
1223a4cd9b30SMilanka Ringwald 
1224a4cd9b30SMilanka Ringwald 				if( cptr->period == cptr->portaperiod )
1225a4cd9b30SMilanka Ringwald 				{
1226a4cd9b30SMilanka Ringwald 					// If the slide is over, don't let it to be retriggered.
1227a4cd9b30SMilanka Ringwald 					cptr->portaperiod = 0;
1228a4cd9b30SMilanka Ringwald 				}
1229a4cd9b30SMilanka Ringwald 			}
1230a4cd9b30SMilanka Ringwald 
12318201da88SMatthias Ringwald 			if( cptr->glissando )
12328201da88SMatthias Ringwald 			{
12338201da88SMatthias Ringwald 				// TODO : Glissando effect.
12348201da88SMatthias Ringwald 			}
12358201da88SMatthias Ringwald 
1236a4cd9b30SMilanka Ringwald 			if( cptr->effect == EFFECT_VOLSLIDE_TONEPORTA )
1237a4cd9b30SMilanka Ringwald 			{
12388201da88SMatthias Ringwald 				if( cptr->volumeslide & 0xF0 )
1239a4cd9b30SMilanka Ringwald 				{
12408201da88SMatthias Ringwald 					cptr->volume += ( cptr->volumeslide >> 4 );
1241a4cd9b30SMilanka Ringwald 
1242a4cd9b30SMilanka Ringwald 					if( cptr->volume > 63 )
1243a4cd9b30SMilanka Ringwald 						cptr->volume = 63;
1244a4cd9b30SMilanka Ringwald 				}
1245a4cd9b30SMilanka Ringwald 				else
1246a4cd9b30SMilanka Ringwald 				{
12478201da88SMatthias Ringwald 					cptr->volume -= ( cptr->volumeslide & 0x0F );
1248a4cd9b30SMilanka Ringwald 
1249a4cd9b30SMilanka Ringwald 					if( cptr->volume > 63 )
1250a4cd9b30SMilanka Ringwald 						cptr->volume = 0;
1251a4cd9b30SMilanka Ringwald 				}
12528201da88SMatthias Ringwald #ifdef HXCMOD_USE_PRECALC_VOLUME_TABLE
12538201da88SMatthias Ringwald 				cptr->volume_table = modctx->volume_selection_table[cptr->volume];
12548201da88SMatthias Ringwald #endif
1255a4cd9b30SMilanka Ringwald 			}
1256a4cd9b30SMilanka Ringwald 		break;
1257a4cd9b30SMilanka Ringwald 
1258a4cd9b30SMilanka Ringwald 		case EFFECT_VOLSLIDE_VIBRATO:
1259a4cd9b30SMilanka Ringwald 		case EFFECT_VIBRATO:
1260a4cd9b30SMilanka Ringwald 
1261a4cd9b30SMilanka Ringwald 			cptr->vibraperiod = ( (cptr->vibraparam&0xF) * sintable[cptr->vibrapointeur&0x1F] )>>7;
1262a4cd9b30SMilanka Ringwald 
1263a4cd9b30SMilanka Ringwald 			if( cptr->vibrapointeur > 31 )
1264a4cd9b30SMilanka Ringwald 				cptr->vibraperiod = -cptr->vibraperiod;
1265a4cd9b30SMilanka Ringwald 
12668201da88SMatthias Ringwald 			cptr->vibrapointeur = ( cptr->vibrapointeur + ( ( cptr->vibraparam>>4 ) & 0x0F) ) & 0x3F;
1267a4cd9b30SMilanka Ringwald 
1268a4cd9b30SMilanka Ringwald 			if( cptr->effect == EFFECT_VOLSLIDE_VIBRATO )
1269a4cd9b30SMilanka Ringwald 			{
12708201da88SMatthias Ringwald 				if( cptr->volumeslide & 0xF0 )
1271a4cd9b30SMilanka Ringwald 				{
1272a4cd9b30SMilanka Ringwald 					cptr->volume += ( cptr->volumeslide >> 4 );
1273a4cd9b30SMilanka Ringwald 
1274a4cd9b30SMilanka Ringwald 					if( cptr->volume > 64 )
1275a4cd9b30SMilanka Ringwald 						cptr->volume = 64;
1276a4cd9b30SMilanka Ringwald 				}
1277a4cd9b30SMilanka Ringwald 				else
1278a4cd9b30SMilanka Ringwald 				{
12798201da88SMatthias Ringwald 					cptr->volume -= cptr->volumeslide;
1280a4cd9b30SMilanka Ringwald 
1281a4cd9b30SMilanka Ringwald 					if( cptr->volume > 64 )
1282a4cd9b30SMilanka Ringwald 						cptr->volume = 0;
1283a4cd9b30SMilanka Ringwald 				}
12848201da88SMatthias Ringwald #ifdef HXCMOD_USE_PRECALC_VOLUME_TABLE
12858201da88SMatthias Ringwald 				cptr->volume_table = modctx->volume_selection_table[cptr->volume];
12868201da88SMatthias Ringwald #endif
12878201da88SMatthias Ringwald 			}
12888201da88SMatthias Ringwald 
1289a4cd9b30SMilanka Ringwald 		break;
1290a4cd9b30SMilanka Ringwald 
12918201da88SMatthias Ringwald 		case EFFECT_VOLUME_SLIDE:
12928201da88SMatthias Ringwald 
12938201da88SMatthias Ringwald 			if( cptr->volumeslide & 0xF0 )
12948201da88SMatthias Ringwald 			{
12958201da88SMatthias Ringwald 				cptr->volume += ( cptr->volumeslide >> 4 );
12968201da88SMatthias Ringwald 
12978201da88SMatthias Ringwald 				if( cptr->volume > 64 )
12988201da88SMatthias Ringwald 					cptr->volume = 64;
12998201da88SMatthias Ringwald 			}
13008201da88SMatthias Ringwald 			else
13018201da88SMatthias Ringwald 			{
13028201da88SMatthias Ringwald 				cptr->volume -= cptr->volumeslide;
13038201da88SMatthias Ringwald 
13048201da88SMatthias Ringwald 				if( cptr->volume > 64 )
13058201da88SMatthias Ringwald 					cptr->volume = 0;
13068201da88SMatthias Ringwald 			}
13078201da88SMatthias Ringwald #ifdef HXCMOD_USE_PRECALC_VOLUME_TABLE
13088201da88SMatthias Ringwald 			cptr->volume_table = modctx->volume_selection_table[cptr->volume];
13098201da88SMatthias Ringwald #endif
13108201da88SMatthias Ringwald 		break;
13118201da88SMatthias Ringwald 
13128201da88SMatthias Ringwald 		case EFFECT_EXTENDED:
13138201da88SMatthias Ringwald 			switch( cptr->parameffect >> 4 )
13148201da88SMatthias Ringwald 			{
13158201da88SMatthias Ringwald 
1316a4cd9b30SMilanka Ringwald 				case EFFECT_E_NOTE_CUT:
1317a4cd9b30SMilanka Ringwald 					if( cptr->cut_param )
1318a4cd9b30SMilanka Ringwald 						cptr->cut_param--;
1319a4cd9b30SMilanka Ringwald 
1320a4cd9b30SMilanka Ringwald 					if( !cptr->cut_param )
13218201da88SMatthias Ringwald 					{
1322a4cd9b30SMilanka Ringwald 						cptr->volume = 0;
13238201da88SMatthias Ringwald #ifdef HXCMOD_USE_PRECALC_VOLUME_TABLE
13248201da88SMatthias Ringwald 						cptr->volume_table = modctx->volume_selection_table[cptr->volume];
13258201da88SMatthias Ringwald #endif
13268201da88SMatthias Ringwald 					}
13278201da88SMatthias Ringwald 				break;
13288201da88SMatthias Ringwald 
13298201da88SMatthias Ringwald 				case EFFECT_E_RETRIGGER_NOTE:
13308201da88SMatthias Ringwald 					cptr->retrig_cnt++;
13318201da88SMatthias Ringwald 					if( cptr->retrig_cnt >= cptr->retrig_param )
13328201da88SMatthias Ringwald 					{
13338201da88SMatthias Ringwald 						cptr->retrig_cnt = 0;
13348201da88SMatthias Ringwald 
13358201da88SMatthias Ringwald 						cptr->sampdata = cptr->lst_sampdata;
13368201da88SMatthias Ringwald 						cptr->length = cptr->lst_length;
13378201da88SMatthias Ringwald 						cptr->reppnt = cptr->lst_reppnt;
13388201da88SMatthias Ringwald 						cptr->replen = cptr->lst_replen;
13398201da88SMatthias Ringwald 						cptr->samppos = 0;
13408201da88SMatthias Ringwald 					}
13418201da88SMatthias Ringwald 				break;
13428201da88SMatthias Ringwald 
13438201da88SMatthias Ringwald 				case EFFECT_E_NOTE_DELAY:
13448201da88SMatthias Ringwald 					if( cptr->note_delay )
13458201da88SMatthias Ringwald 					{
13468201da88SMatthias Ringwald 						if( (unsigned char)( cptr->note_delay - 1 ) == modctx->tick_cnt )
13478201da88SMatthias Ringwald 						{
13488201da88SMatthias Ringwald 							cptr->sampdata = cptr->dly_sampdata;
13498201da88SMatthias Ringwald 							cptr->length = cptr->dly_length;
13508201da88SMatthias Ringwald 							cptr->reppnt = cptr->dly_reppnt;
13518201da88SMatthias Ringwald 							cptr->replen = cptr->dly_replen;
13528201da88SMatthias Ringwald 
13538201da88SMatthias Ringwald 							cptr->lst_sampdata = cptr->sampdata;
13548201da88SMatthias Ringwald 							cptr->lst_length = cptr->length;
13558201da88SMatthias Ringwald 							cptr->lst_reppnt = cptr->reppnt;
13568201da88SMatthias Ringwald 							cptr->lst_replen = cptr->replen;
13578201da88SMatthias Ringwald 							cptr->note_delay = 0;
13588201da88SMatthias Ringwald 						}
13598201da88SMatthias Ringwald 					}
13608201da88SMatthias Ringwald 				break;
13618201da88SMatthias Ringwald 				default:
13628201da88SMatthias Ringwald 				break;
13638201da88SMatthias Ringwald 			}
1364a4cd9b30SMilanka Ringwald 		break;
1365a4cd9b30SMilanka Ringwald 
1366a4cd9b30SMilanka Ringwald 		default:
1367a4cd9b30SMilanka Ringwald 		break;
1368a4cd9b30SMilanka Ringwald 
1369a4cd9b30SMilanka Ringwald 	}
1370a4cd9b30SMilanka Ringwald 
1371a4cd9b30SMilanka Ringwald }
1372a4cd9b30SMilanka Ringwald 
1373a4cd9b30SMilanka Ringwald ///////////////////////////////////////////////////////////////////////////////////
1374a4cd9b30SMilanka Ringwald int hxcmod_init(modcontext * modctx)
1375a4cd9b30SMilanka Ringwald {
13768201da88SMatthias Ringwald #ifdef HXCMOD_USE_PRECALC_VOLUME_TABLE
13778201da88SMatthias Ringwald 	muint c;
13788201da88SMatthias Ringwald 	mint  i,j;
13798201da88SMatthias Ringwald #endif
1380a4cd9b30SMilanka Ringwald 	if( modctx )
1381a4cd9b30SMilanka Ringwald 	{
1382a4cd9b30SMilanka Ringwald 		memclear(modctx,0,sizeof(modcontext));
1383a4cd9b30SMilanka Ringwald 		modctx->playrate = 44100;
1384a4cd9b30SMilanka Ringwald 		modctx->stereo = 1;
1385a4cd9b30SMilanka Ringwald 		modctx->stereo_separation = 1;
1386a4cd9b30SMilanka Ringwald 		modctx->bits = 16;
1387a4cd9b30SMilanka Ringwald 		modctx->filter = 1;
1388a4cd9b30SMilanka Ringwald 
13898201da88SMatthias Ringwald #ifdef HXCMOD_USE_PRECALC_VOLUME_TABLE
13908201da88SMatthias Ringwald 		c = 0;
13918201da88SMatthias Ringwald 		for(i=0;i<65;i++)
1392a4cd9b30SMilanka Ringwald 		{
13938201da88SMatthias Ringwald 			for(j=-128;j<128;j++)
1394a4cd9b30SMilanka Ringwald 			{
13958201da88SMatthias Ringwald 				modctx->precalc_volume_array[c] = i * j;
13968201da88SMatthias Ringwald 				c++;
1397a4cd9b30SMilanka Ringwald 			}
13988201da88SMatthias Ringwald 
13998201da88SMatthias Ringwald 			modctx->volume_selection_table[i] = &modctx->precalc_volume_array[(i*256) + 128];
1400a4cd9b30SMilanka Ringwald 		}
14018201da88SMatthias Ringwald #endif
1402a4cd9b30SMilanka Ringwald 
1403a4cd9b30SMilanka Ringwald 		return 1;
1404a4cd9b30SMilanka Ringwald 	}
1405a4cd9b30SMilanka Ringwald 
1406a4cd9b30SMilanka Ringwald 	return 0;
1407a4cd9b30SMilanka Ringwald }
1408a4cd9b30SMilanka Ringwald 
14098201da88SMatthias Ringwald int hxcmod_setcfg(modcontext * modctx, int samplerate, int stereo_separation, int filter)
1410a4cd9b30SMilanka Ringwald {
1411a4cd9b30SMilanka Ringwald 	if( modctx )
1412a4cd9b30SMilanka Ringwald 	{
1413a4cd9b30SMilanka Ringwald 		modctx->playrate = samplerate;
1414a4cd9b30SMilanka Ringwald 
1415a4cd9b30SMilanka Ringwald 		if(stereo_separation < 4)
1416a4cd9b30SMilanka Ringwald 		{
1417a4cd9b30SMilanka Ringwald 			modctx->stereo_separation = stereo_separation;
1418a4cd9b30SMilanka Ringwald 		}
1419a4cd9b30SMilanka Ringwald 
1420a4cd9b30SMilanka Ringwald 		if( filter )
1421a4cd9b30SMilanka Ringwald 			modctx->filter = 1;
1422a4cd9b30SMilanka Ringwald 		else
1423a4cd9b30SMilanka Ringwald 			modctx->filter = 0;
1424a4cd9b30SMilanka Ringwald 
1425a4cd9b30SMilanka Ringwald 		return 1;
1426a4cd9b30SMilanka Ringwald 	}
1427a4cd9b30SMilanka Ringwald 
1428a4cd9b30SMilanka Ringwald 	return 0;
1429a4cd9b30SMilanka Ringwald }
1430a4cd9b30SMilanka Ringwald 
1431a4cd9b30SMilanka Ringwald int hxcmod_load( modcontext * modctx, void * mod_data, int mod_data_size )
1432a4cd9b30SMilanka Ringwald {
14338201da88SMatthias Ringwald 	muint i, j, max, digitfactor;
1434a4cd9b30SMilanka Ringwald 	sample *sptr;
1435a4cd9b30SMilanka Ringwald 	unsigned char * modmemory,* endmodmemory;
1436a4cd9b30SMilanka Ringwald 
1437a4cd9b30SMilanka Ringwald 	modmemory = (unsigned char *)mod_data;
1438a4cd9b30SMilanka Ringwald 	endmodmemory = modmemory + mod_data_size;
1439a4cd9b30SMilanka Ringwald 
1440a4cd9b30SMilanka Ringwald 	if( modmemory )
1441a4cd9b30SMilanka Ringwald 	{
1442a4cd9b30SMilanka Ringwald 		if( modctx )
1443a4cd9b30SMilanka Ringwald 		{
14448201da88SMatthias Ringwald #ifdef FULL_STATE
14458201da88SMatthias Ringwald 			memclear(&(modctx->effects_event_counts),0,sizeof(modctx->effects_event_counts));
14468201da88SMatthias Ringwald #endif
14478201da88SMatthias Ringwald 			memcopy(&(modctx->song),modmemory,1084);
1448a4cd9b30SMilanka Ringwald 
1449a4cd9b30SMilanka Ringwald 			i = 0;
1450a4cd9b30SMilanka Ringwald 			modctx->number_of_channels = 0;
14518201da88SMatthias Ringwald 			while(modlist[i].numberofchannels && !modctx->number_of_channels)
1452a4cd9b30SMilanka Ringwald 			{
14538201da88SMatthias Ringwald 				digitfactor = 0;
14548201da88SMatthias Ringwald 
14558201da88SMatthias Ringwald 				j = 0;
14568201da88SMatthias Ringwald 				while( j < 4 )
1457a4cd9b30SMilanka Ringwald 				{
14588201da88SMatthias Ringwald 					if( modlist[i].signature[j] == '$' )
14598201da88SMatthias Ringwald 					{
14608201da88SMatthias Ringwald 						if(digitfactor)
14618201da88SMatthias Ringwald 							digitfactor *= 10;
14628201da88SMatthias Ringwald 						else
14638201da88SMatthias Ringwald 							digitfactor = 1;
14648201da88SMatthias Ringwald 					}
14658201da88SMatthias Ringwald 					j++;
14668201da88SMatthias Ringwald 				}
14678201da88SMatthias Ringwald 
14688201da88SMatthias Ringwald 				modctx->number_of_channels = 0;
14698201da88SMatthias Ringwald 
14708201da88SMatthias Ringwald 				j = 0;
14718201da88SMatthias Ringwald 				while( j < 4 )
14728201da88SMatthias Ringwald 				{
14738201da88SMatthias Ringwald 					if( (modlist[i].signature[j] == modctx->song.signature[j]) || modlist[i].signature[j] == '$' )
14748201da88SMatthias Ringwald 					{
14758201da88SMatthias Ringwald 						if( modlist[i].signature[j] == '$' )
14768201da88SMatthias Ringwald 						{
14778201da88SMatthias Ringwald 							if(modctx->song.signature[j] >= '0' && modctx->song.signature[j] <= '9')
14788201da88SMatthias Ringwald 							{
14798201da88SMatthias Ringwald 								modctx->number_of_channels += (modctx->song.signature[j] - '0') * digitfactor;
14808201da88SMatthias Ringwald 								digitfactor /= 10;
14818201da88SMatthias Ringwald 							}
14828201da88SMatthias Ringwald 							else
14838201da88SMatthias Ringwald 							{
14848201da88SMatthias Ringwald 								modctx->number_of_channels = 0;
14858201da88SMatthias Ringwald 								break;
14868201da88SMatthias Ringwald 							}
14878201da88SMatthias Ringwald 						}
14888201da88SMatthias Ringwald 						j++;
14898201da88SMatthias Ringwald 					}
14908201da88SMatthias Ringwald 					else
14918201da88SMatthias Ringwald 					{
14928201da88SMatthias Ringwald 						modctx->number_of_channels = 0;
14938201da88SMatthias Ringwald 						break;
14948201da88SMatthias Ringwald 					}
14958201da88SMatthias Ringwald 				}
14968201da88SMatthias Ringwald 
14978201da88SMatthias Ringwald 				if( j == 4 )
14988201da88SMatthias Ringwald 				{
14998201da88SMatthias Ringwald 					if(!modctx->number_of_channels)
1500a4cd9b30SMilanka Ringwald 						modctx->number_of_channels = modlist[i].numberofchannels;
1501a4cd9b30SMilanka Ringwald 				}
1502a4cd9b30SMilanka Ringwald 
1503a4cd9b30SMilanka Ringwald 				i++;
1504a4cd9b30SMilanka Ringwald 			}
1505a4cd9b30SMilanka Ringwald 
1506a4cd9b30SMilanka Ringwald 			if( !modctx->number_of_channels )
1507a4cd9b30SMilanka Ringwald 			{
1508a4cd9b30SMilanka Ringwald 				// 15 Samples modules support
1509a4cd9b30SMilanka Ringwald 				// Shift the whole datas to make it look likes a standard 4 channels mod.
15108201da88SMatthias Ringwald 				memcopy(&(modctx->song.signature), "M.K.", 4);
1511a4cd9b30SMilanka Ringwald 				memcopy(&(modctx->song.length), &(modctx->song.samples[15]), 130);
1512a4cd9b30SMilanka Ringwald 				memclear(&(modctx->song.samples[15]), 0, 480);
1513a4cd9b30SMilanka Ringwald 				modmemory += 600;
1514a4cd9b30SMilanka Ringwald 				modctx->number_of_channels = 4;
1515a4cd9b30SMilanka Ringwald 			}
1516a4cd9b30SMilanka Ringwald 			else
1517a4cd9b30SMilanka Ringwald 			{
1518a4cd9b30SMilanka Ringwald 				modmemory += 1084;
1519a4cd9b30SMilanka Ringwald 			}
1520a4cd9b30SMilanka Ringwald 
15218201da88SMatthias Ringwald 			if( modctx->number_of_channels > NUMMAXCHANNELS )
15228201da88SMatthias Ringwald 				return 0; // Too much channels ! - Increase/define HXCMOD_MAXCHANNELS !
15238201da88SMatthias Ringwald 
1524a4cd9b30SMilanka Ringwald 			if( modmemory >= endmodmemory )
1525a4cd9b30SMilanka Ringwald 				return 0; // End passed ? - Probably a bad file !
1526a4cd9b30SMilanka Ringwald 
1527a4cd9b30SMilanka Ringwald 			// Patterns loading
1528a4cd9b30SMilanka Ringwald 			for (i = max = 0; i < 128; i++)
1529a4cd9b30SMilanka Ringwald 			{
1530a4cd9b30SMilanka Ringwald 				while (max <= modctx->song.patterntable[i])
1531a4cd9b30SMilanka Ringwald 				{
1532a4cd9b30SMilanka Ringwald 					modctx->patterndata[max] = (note*)modmemory;
1533a4cd9b30SMilanka Ringwald 					modmemory += (256*modctx->number_of_channels);
1534a4cd9b30SMilanka Ringwald 					max++;
1535a4cd9b30SMilanka Ringwald 
1536a4cd9b30SMilanka Ringwald 					if( modmemory >= endmodmemory )
1537a4cd9b30SMilanka Ringwald 						return 0; // End passed ? - Probably a bad file !
1538a4cd9b30SMilanka Ringwald 				}
1539a4cd9b30SMilanka Ringwald 			}
1540a4cd9b30SMilanka Ringwald 
1541a4cd9b30SMilanka Ringwald 			for (i = 0; i < 31; i++)
1542a4cd9b30SMilanka Ringwald 				modctx->sampledata[i]=0;
1543a4cd9b30SMilanka Ringwald 
1544a4cd9b30SMilanka Ringwald 			// Samples loading
1545a4cd9b30SMilanka Ringwald 			for (i = 0, sptr = modctx->song.samples; i <31; i++, sptr++)
1546a4cd9b30SMilanka Ringwald 			{
1547a4cd9b30SMilanka Ringwald 				if (sptr->length == 0) continue;
1548a4cd9b30SMilanka Ringwald 
1549afc6fe18SMatthias Ringwald 				modctx->sampledata[i] = (mchar*)modmemory;
15508201da88SMatthias Ringwald 				modmemory += (GET_BGI_W(sptr->length)*2);
1551a4cd9b30SMilanka Ringwald 
15528201da88SMatthias Ringwald 				if (GET_BGI_W(sptr->replen) + GET_BGI_W(sptr->reppnt) > GET_BGI_W(sptr->length))
15538201da88SMatthias Ringwald 					sptr->replen = GET_BGI_W((GET_BGI_W(sptr->length) - GET_BGI_W(sptr->reppnt)));
1554a4cd9b30SMilanka Ringwald 
1555a4cd9b30SMilanka Ringwald 				if( modmemory > endmodmemory )
1556a4cd9b30SMilanka Ringwald 					return 0; // End passed ? - Probably a bad file !
1557a4cd9b30SMilanka Ringwald 			}
1558a4cd9b30SMilanka Ringwald 
1559a4cd9b30SMilanka Ringwald 			// States init
1560a4cd9b30SMilanka Ringwald 
1561a4cd9b30SMilanka Ringwald 			modctx->tablepos = 0;
1562a4cd9b30SMilanka Ringwald 			modctx->patternpos = 0;
1563a4cd9b30SMilanka Ringwald 			modctx->song.speed = 6;
1564a4cd9b30SMilanka Ringwald 			modctx->bpm = 125;
1565a4cd9b30SMilanka Ringwald 
15668201da88SMatthias Ringwald #ifdef HXCMOD_16BITS_TARGET
15678201da88SMatthias Ringwald 			// song.speed = 1 <> 31
15688201da88SMatthias Ringwald 			// playrate = 8000 <> 22050
15698201da88SMatthias Ringwald 			// bpm = 32 <> 255
1570a4cd9b30SMilanka Ringwald 
15718201da88SMatthias Ringwald 			modctx->patternticksem = (muint)( ( (mulong)modctx->playrate * 5 ) / ( (muint)modctx->bpm * 2 ) );
15728201da88SMatthias Ringwald #else
15738201da88SMatthias Ringwald 			// song.speed = 1 <> 31
15748201da88SMatthias Ringwald 			// playrate = 8000 <> 96000
15758201da88SMatthias Ringwald 			// bpm = 32 <> 255
15768201da88SMatthias Ringwald 
15778201da88SMatthias Ringwald 			modctx->patternticksem = ( ( modctx->playrate * 5 ) / ( (mulong)modctx->bpm * 2 ) );
15788201da88SMatthias Ringwald #endif
15798201da88SMatthias Ringwald 			modctx->patternticksaim = modctx->song.speed * modctx->patternticksem;
15808201da88SMatthias Ringwald 
15818201da88SMatthias Ringwald 			modctx->patternticks = modctx->patternticksaim + 1;
15828201da88SMatthias Ringwald 
15838201da88SMatthias Ringwald 			modctx->sampleticksconst = ((3546894UL * 16) / modctx->playrate) << 6; //8448*428/playrate;
1584a4cd9b30SMilanka Ringwald 
1585a4cd9b30SMilanka Ringwald 			for(i=0; i < modctx->number_of_channels; i++)
1586a4cd9b30SMilanka Ringwald 			{
1587a4cd9b30SMilanka Ringwald 				modctx->channels[i].volume = 0;
1588a4cd9b30SMilanka Ringwald 				modctx->channels[i].period = 0;
15898201da88SMatthias Ringwald #ifdef HXCMOD_USE_PRECALC_VOLUME_TABLE
15908201da88SMatthias Ringwald 				modctx->channels[i].volume_table = modctx->volume_selection_table[0];
15918201da88SMatthias Ringwald #endif
1592a4cd9b30SMilanka Ringwald 			}
1593a4cd9b30SMilanka Ringwald 
1594a4cd9b30SMilanka Ringwald 			modctx->mod_loaded = 1;
1595a4cd9b30SMilanka Ringwald 
1596a4cd9b30SMilanka Ringwald 			return 1;
1597a4cd9b30SMilanka Ringwald 		}
1598a4cd9b30SMilanka Ringwald 	}
1599a4cd9b30SMilanka Ringwald 
1600a4cd9b30SMilanka Ringwald 	return 0;
1601a4cd9b30SMilanka Ringwald }
1602a4cd9b30SMilanka Ringwald 
16038201da88SMatthias Ringwald void hxcmod_fillbuffer(modcontext * modctx, msample * outbuffer, mssize nbsample, tracker_buffer_state * trkbuf)
1604a4cd9b30SMilanka Ringwald {
16058201da88SMatthias Ringwald 	mssize i;
16068201da88SMatthias Ringwald 	muint  j;
16078201da88SMatthias Ringwald 	muint c;
16088201da88SMatthias Ringwald 
1609a4cd9b30SMilanka Ringwald 	unsigned long k;
1610a4cd9b30SMilanka Ringwald 	unsigned int state_remaining_steps;
16118201da88SMatthias Ringwald 
16128201da88SMatthias Ringwald #ifdef HXCMOD_OUTPUT_FILTER
16138201da88SMatthias Ringwald #ifndef HXCMOD_MONO_OUTPUT
16148201da88SMatthias Ringwald 	int ll,tl;
16158201da88SMatthias Ringwald #endif
16168201da88SMatthias Ringwald 	int lr,tr;
16178201da88SMatthias Ringwald #endif
16188201da88SMatthias Ringwald 
16198201da88SMatthias Ringwald #ifndef HXCMOD_MONO_OUTPUT
16208201da88SMatthias Ringwald 	int l;
16218201da88SMatthias Ringwald #endif
16228201da88SMatthias Ringwald 	int r;
16238201da88SMatthias Ringwald 
1624a4cd9b30SMilanka Ringwald 	short finalperiod;
1625a4cd9b30SMilanka Ringwald 	note	*nptr;
16268201da88SMatthias Ringwald 	channel *cptr;
1627a4cd9b30SMilanka Ringwald 
1628a4cd9b30SMilanka Ringwald 	if( modctx && outbuffer )
1629a4cd9b30SMilanka Ringwald 	{
1630a4cd9b30SMilanka Ringwald 		if(modctx->mod_loaded)
1631a4cd9b30SMilanka Ringwald 		{
1632a4cd9b30SMilanka Ringwald 			state_remaining_steps = 0;
1633a4cd9b30SMilanka Ringwald 
16348201da88SMatthias Ringwald #ifdef HXCMOD_STATE_REPORT_SUPPORT
1635a4cd9b30SMilanka Ringwald 			if( trkbuf )
1636a4cd9b30SMilanka Ringwald 			{
1637a4cd9b30SMilanka Ringwald 				trkbuf->cur_rd_index = 0;
1638a4cd9b30SMilanka Ringwald 
1639a4cd9b30SMilanka Ringwald 				memcopy(trkbuf->name,modctx->song.title,sizeof(modctx->song.title));
1640a4cd9b30SMilanka Ringwald 
1641a4cd9b30SMilanka Ringwald 				for(i=0;i<31;i++)
1642a4cd9b30SMilanka Ringwald 				{
1643a4cd9b30SMilanka Ringwald 					memcopy(trkbuf->instruments[i].name,modctx->song.samples[i].name,sizeof(trkbuf->instruments[i].name));
1644a4cd9b30SMilanka Ringwald 				}
1645a4cd9b30SMilanka Ringwald 			}
16468201da88SMatthias Ringwald #endif
1647a4cd9b30SMilanka Ringwald 
16488201da88SMatthias Ringwald #ifdef HXCMOD_OUTPUT_FILTER
16498201da88SMatthias Ringwald 	#ifndef HXCMOD_MONO_OUTPUT
1650a4cd9b30SMilanka Ringwald 			ll = modctx->last_l_sample;
16518201da88SMatthias Ringwald 	#endif
1652a4cd9b30SMilanka Ringwald 			lr = modctx->last_r_sample;
16538201da88SMatthias Ringwald #endif
1654a4cd9b30SMilanka Ringwald 
1655a4cd9b30SMilanka Ringwald 			for (i = 0; i < nbsample; i++)
1656a4cd9b30SMilanka Ringwald 			{
1657a4cd9b30SMilanka Ringwald 				//---------------------------------------
1658a4cd9b30SMilanka Ringwald 				if( modctx->patternticks++ > modctx->patternticksaim )
1659a4cd9b30SMilanka Ringwald 				{
1660a4cd9b30SMilanka Ringwald 					if( !modctx->patterndelay )
1661a4cd9b30SMilanka Ringwald 					{
1662a4cd9b30SMilanka Ringwald 						nptr = modctx->patterndata[modctx->song.patterntable[modctx->tablepos]];
1663a4cd9b30SMilanka Ringwald 						nptr = nptr + modctx->patternpos;
1664a4cd9b30SMilanka Ringwald 						cptr = modctx->channels;
1665a4cd9b30SMilanka Ringwald 
16668201da88SMatthias Ringwald 						modctx->tick_cnt = 0;
16678201da88SMatthias Ringwald 
1668a4cd9b30SMilanka Ringwald 						modctx->patternticks = 0;
1669a4cd9b30SMilanka Ringwald 						modctx->patterntickse = 0;
1670a4cd9b30SMilanka Ringwald 
1671a4cd9b30SMilanka Ringwald 						for(c=0;c<modctx->number_of_channels;c++)
1672a4cd9b30SMilanka Ringwald 						{
16738201da88SMatthias Ringwald 							worknote((note*)(nptr), (channel*)(cptr),(char)(c+1),modctx);
16748201da88SMatthias Ringwald 
16758201da88SMatthias Ringwald 							if (cptr->period != 0)
16768201da88SMatthias Ringwald 							{
16778201da88SMatthias Ringwald 								finalperiod = cptr->period - cptr->decalperiod - cptr->vibraperiod;
16788201da88SMatthias Ringwald 								if (finalperiod)
16798201da88SMatthias Ringwald 								{
16808201da88SMatthias Ringwald 									cptr->sampinc = ((modctx->sampleticksconst) / finalperiod);
16818201da88SMatthias Ringwald 								}
16828201da88SMatthias Ringwald 								else
16838201da88SMatthias Ringwald 								{
16848201da88SMatthias Ringwald 									cptr->sampinc = 0;
16858201da88SMatthias Ringwald 								}
16868201da88SMatthias Ringwald 							}
16878201da88SMatthias Ringwald 							else
16888201da88SMatthias Ringwald 								cptr->sampinc = 0;
16898201da88SMatthias Ringwald 
16908201da88SMatthias Ringwald 							nptr++;
16918201da88SMatthias Ringwald 							cptr++;
1692a4cd9b30SMilanka Ringwald 						}
1693a4cd9b30SMilanka Ringwald 
1694a4cd9b30SMilanka Ringwald 						if( !modctx->jump_loop_effect )
1695a4cd9b30SMilanka Ringwald 							modctx->patternpos += modctx->number_of_channels;
1696a4cd9b30SMilanka Ringwald 						else
1697a4cd9b30SMilanka Ringwald 							modctx->jump_loop_effect = 0;
1698a4cd9b30SMilanka Ringwald 
1699a4cd9b30SMilanka Ringwald 						if( modctx->patternpos == 64*modctx->number_of_channels )
1700a4cd9b30SMilanka Ringwald 						{
1701a4cd9b30SMilanka Ringwald 							modctx->tablepos++;
1702a4cd9b30SMilanka Ringwald 							modctx->patternpos = 0;
1703a4cd9b30SMilanka Ringwald 							if(modctx->tablepos >= modctx->song.length)
1704a4cd9b30SMilanka Ringwald 								modctx->tablepos = 0;
1705a4cd9b30SMilanka Ringwald 						}
1706a4cd9b30SMilanka Ringwald 					}
1707a4cd9b30SMilanka Ringwald 					else
1708a4cd9b30SMilanka Ringwald 					{
1709a4cd9b30SMilanka Ringwald 						modctx->patterndelay--;
1710a4cd9b30SMilanka Ringwald 						modctx->patternticks = 0;
1711a4cd9b30SMilanka Ringwald 						modctx->patterntickse = 0;
17128201da88SMatthias Ringwald 						modctx->tick_cnt = 0;
1713a4cd9b30SMilanka Ringwald 					}
1714a4cd9b30SMilanka Ringwald 
1715a4cd9b30SMilanka Ringwald 				}
1716a4cd9b30SMilanka Ringwald 
17178201da88SMatthias Ringwald 				if (modctx->patterntickse++ > modctx->patternticksem)
1718a4cd9b30SMilanka Ringwald 				{
1719a4cd9b30SMilanka Ringwald 					nptr = modctx->patterndata[modctx->song.patterntable[modctx->tablepos]];
1720a4cd9b30SMilanka Ringwald 					nptr = nptr + modctx->patternpos;
1721a4cd9b30SMilanka Ringwald 					cptr = modctx->channels;
1722a4cd9b30SMilanka Ringwald 
1723a4cd9b30SMilanka Ringwald 					for(c=0;c<modctx->number_of_channels;c++)
1724a4cd9b30SMilanka Ringwald 					{
17258201da88SMatthias Ringwald 						workeffect( modctx, nptr, cptr );
17268201da88SMatthias Ringwald 
17278201da88SMatthias Ringwald 						if (cptr->period != 0)
17288201da88SMatthias Ringwald 						{
17298201da88SMatthias Ringwald 							finalperiod = cptr->period - cptr->decalperiod - cptr->vibraperiod;
17308201da88SMatthias Ringwald 							if (finalperiod)
17318201da88SMatthias Ringwald 							{
17328201da88SMatthias Ringwald 								cptr->sampinc = ((modctx->sampleticksconst) / finalperiod);
17338201da88SMatthias Ringwald 							}
17348201da88SMatthias Ringwald 							else
17358201da88SMatthias Ringwald 							{
17368201da88SMatthias Ringwald 								cptr->sampinc = 0;
17378201da88SMatthias Ringwald 							}
17388201da88SMatthias Ringwald 						}
17398201da88SMatthias Ringwald 						else
17408201da88SMatthias Ringwald 							cptr->sampinc = 0;
17418201da88SMatthias Ringwald 
17428201da88SMatthias Ringwald 						nptr++;
17438201da88SMatthias Ringwald 						cptr++;
1744a4cd9b30SMilanka Ringwald 					}
1745a4cd9b30SMilanka Ringwald 
17468201da88SMatthias Ringwald 					modctx->tick_cnt++;
1747a4cd9b30SMilanka Ringwald 					modctx->patterntickse = 0;
1748a4cd9b30SMilanka Ringwald 				}
1749a4cd9b30SMilanka Ringwald 
1750a4cd9b30SMilanka Ringwald 				//---------------------------------------
1751a4cd9b30SMilanka Ringwald 
17528201da88SMatthias Ringwald #ifdef HXCMOD_STATE_REPORT_SUPPORT
1753a4cd9b30SMilanka Ringwald 				if( trkbuf && !state_remaining_steps )
1754a4cd9b30SMilanka Ringwald 				{
1755a4cd9b30SMilanka Ringwald 					if( trkbuf->nb_of_state < trkbuf->nb_max_of_state )
1756a4cd9b30SMilanka Ringwald 					{
1757a4cd9b30SMilanka Ringwald 						memclear(&trkbuf->track_state_buf[trkbuf->nb_of_state],0,sizeof(tracker_state));
1758a4cd9b30SMilanka Ringwald 					}
1759a4cd9b30SMilanka Ringwald 				}
17608201da88SMatthias Ringwald #endif
1761a4cd9b30SMilanka Ringwald 
17628201da88SMatthias Ringwald #ifndef HXCMOD_MONO_OUTPUT
1763a4cd9b30SMilanka Ringwald 				l=0;
17648201da88SMatthias Ringwald #endif
1765a4cd9b30SMilanka Ringwald 				r=0;
1766a4cd9b30SMilanka Ringwald 
1767a4cd9b30SMilanka Ringwald 				for( j = 0, cptr = modctx->channels; j < modctx->number_of_channels ; j++, cptr++)
1768a4cd9b30SMilanka Ringwald 				{
1769a4cd9b30SMilanka Ringwald 					if( cptr->period != 0 )
1770a4cd9b30SMilanka Ringwald 					{
17718201da88SMatthias Ringwald 						cptr->samppos += cptr->sampinc;
1772a4cd9b30SMilanka Ringwald 
17738201da88SMatthias Ringwald 						if( cptr->replen < 2 )
1774a4cd9b30SMilanka Ringwald 						{
17758201da88SMatthias Ringwald 							if( ( cptr->samppos >> 11) >= cptr->length )
1776a4cd9b30SMilanka Ringwald 							{
1777a4cd9b30SMilanka Ringwald 								cptr->length = 0;
1778a4cd9b30SMilanka Ringwald 								cptr->reppnt = 0;
1779a4cd9b30SMilanka Ringwald 
17808201da88SMatthias Ringwald 								if(cptr->update_nxt_repeat)
17818201da88SMatthias Ringwald 								{
17828201da88SMatthias Ringwald 									cptr->replen = cptr->nxt_replen;
17838201da88SMatthias Ringwald 									cptr->reppnt = cptr->nxt_reppnt;
17848201da88SMatthias Ringwald 									cptr->sampdata = cptr->nxt_sampdata;
17858201da88SMatthias Ringwald 									cptr->length = cptr->nxt_length;
17868201da88SMatthias Ringwald 
17878201da88SMatthias Ringwald 									cptr->lst_sampdata = cptr->sampdata;
17888201da88SMatthias Ringwald 									cptr->lst_length = cptr->length;
17898201da88SMatthias Ringwald 									cptr->lst_reppnt = cptr->reppnt;
17908201da88SMatthias Ringwald 									cptr->lst_replen = cptr->replen;
17918201da88SMatthias Ringwald 
17928201da88SMatthias Ringwald 									cptr->update_nxt_repeat = 0;
17938201da88SMatthias Ringwald 								}
17948201da88SMatthias Ringwald 
1795a4cd9b30SMilanka Ringwald 								if( cptr->length )
17968201da88SMatthias Ringwald 									cptr->samppos = cptr->samppos % (((unsigned long)cptr->length)<<11);
1797a4cd9b30SMilanka Ringwald 								else
1798a4cd9b30SMilanka Ringwald 									cptr->samppos = 0;
1799a4cd9b30SMilanka Ringwald 							}
1800a4cd9b30SMilanka Ringwald 						}
1801a4cd9b30SMilanka Ringwald 						else
1802a4cd9b30SMilanka Ringwald 						{
18038201da88SMatthias Ringwald 							if( ( cptr->samppos >> 11 ) >= (unsigned long)(cptr->replen+cptr->reppnt) )
1804a4cd9b30SMilanka Ringwald 							{
18058201da88SMatthias Ringwald 								if( cptr->update_nxt_repeat )
18068201da88SMatthias Ringwald 								{
18078201da88SMatthias Ringwald 									cptr->replen = cptr->nxt_replen;
18088201da88SMatthias Ringwald 									cptr->reppnt = cptr->nxt_reppnt;
18098201da88SMatthias Ringwald 									cptr->sampdata = cptr->nxt_sampdata;
18108201da88SMatthias Ringwald 									cptr->length = cptr->nxt_length;
18118201da88SMatthias Ringwald 
18128201da88SMatthias Ringwald 									cptr->lst_sampdata = cptr->sampdata;
18138201da88SMatthias Ringwald 									cptr->lst_length = cptr->length;
18148201da88SMatthias Ringwald 									cptr->lst_reppnt = cptr->reppnt;
18158201da88SMatthias Ringwald 									cptr->lst_replen = cptr->replen;
18168201da88SMatthias Ringwald 
18178201da88SMatthias Ringwald 									cptr->update_nxt_repeat = 0;
18188201da88SMatthias Ringwald 								}
18198201da88SMatthias Ringwald 
18208201da88SMatthias Ringwald 								if( cptr->sampdata )
18218201da88SMatthias Ringwald 								{
18228201da88SMatthias Ringwald 									cptr->samppos = ((unsigned long)(cptr->reppnt)<<11) + (cptr->samppos % ((unsigned long)(cptr->replen+cptr->reppnt)<<11));
18238201da88SMatthias Ringwald 								}
1824a4cd9b30SMilanka Ringwald 							}
1825a4cd9b30SMilanka Ringwald 						}
1826a4cd9b30SMilanka Ringwald 
1827a4cd9b30SMilanka Ringwald 						k = cptr->samppos >> 10;
1828a4cd9b30SMilanka Ringwald 
18298201da88SMatthias Ringwald #ifdef HXCMOD_MONO_OUTPUT
18308201da88SMatthias Ringwald 						if( cptr->sampdata!=0 )
1831a4cd9b30SMilanka Ringwald 						{
18328201da88SMatthias Ringwald #ifdef HXCMOD_USE_PRECALC_VOLUME_TABLE
18338201da88SMatthias Ringwald 							r += cptr->volume_table[cptr->sampdata[k]];
18348201da88SMatthias Ringwald #else
1835a4cd9b30SMilanka Ringwald 							r += ( cptr->sampdata[k] *  cptr->volume );
18368201da88SMatthias Ringwald #endif
1837a4cd9b30SMilanka Ringwald 						}
18388201da88SMatthias Ringwald #else
18398201da88SMatthias Ringwald 						if (cptr->sampdata != 0)
1840a4cd9b30SMilanka Ringwald 						{
18418201da88SMatthias Ringwald 							if ( !(j & 3) || ((j & 3) == 3) )
18428201da88SMatthias Ringwald 							{
18438201da88SMatthias Ringwald #ifdef HXCMOD_USE_PRECALC_VOLUME_TABLE
18448201da88SMatthias Ringwald 								l += cptr->volume_table[cptr->sampdata[k]];
18458201da88SMatthias Ringwald #else
1846a4cd9b30SMilanka Ringwald 								l += (cptr->sampdata[k] * cptr->volume);
18478201da88SMatthias Ringwald #endif
1848a4cd9b30SMilanka Ringwald 							}
18498201da88SMatthias Ringwald 							else
18508201da88SMatthias Ringwald 							{
18518201da88SMatthias Ringwald #ifdef HXCMOD_USE_PRECALC_VOLUME_TABLE
18528201da88SMatthias Ringwald 								r += cptr->volume_table[cptr->sampdata[k]];
18538201da88SMatthias Ringwald #else
18548201da88SMatthias Ringwald 								r += (cptr->sampdata[k] * cptr->volume);
18558201da88SMatthias Ringwald #endif
18568201da88SMatthias Ringwald 							}
18578201da88SMatthias Ringwald 						}
18588201da88SMatthias Ringwald #endif
1859a4cd9b30SMilanka Ringwald 
18608201da88SMatthias Ringwald #ifdef HXCMOD_STATE_REPORT_SUPPORT
1861a4cd9b30SMilanka Ringwald 						if( trkbuf && !state_remaining_steps )
1862a4cd9b30SMilanka Ringwald 						{
1863a4cd9b30SMilanka Ringwald 							if( trkbuf->nb_of_state < trkbuf->nb_max_of_state )
1864a4cd9b30SMilanka Ringwald 							{
1865a4cd9b30SMilanka Ringwald 								trkbuf->track_state_buf[trkbuf->nb_of_state].number_of_tracks = modctx->number_of_channels;
1866a4cd9b30SMilanka Ringwald 								trkbuf->track_state_buf[trkbuf->nb_of_state].buf_index = i;
1867a4cd9b30SMilanka Ringwald 								trkbuf->track_state_buf[trkbuf->nb_of_state].cur_pattern = modctx->song.patterntable[modctx->tablepos];
1868a4cd9b30SMilanka Ringwald 								trkbuf->track_state_buf[trkbuf->nb_of_state].cur_pattern_pos = modctx->patternpos / modctx->number_of_channels;
1869a4cd9b30SMilanka Ringwald 								trkbuf->track_state_buf[trkbuf->nb_of_state].cur_pattern_table_pos = modctx->tablepos;
1870a4cd9b30SMilanka Ringwald 								trkbuf->track_state_buf[trkbuf->nb_of_state].bpm = modctx->bpm;
1871a4cd9b30SMilanka Ringwald 								trkbuf->track_state_buf[trkbuf->nb_of_state].speed = modctx->song.speed;
1872a4cd9b30SMilanka Ringwald 								trkbuf->track_state_buf[trkbuf->nb_of_state].tracks[j].cur_effect = cptr->effect_code;
1873a4cd9b30SMilanka Ringwald 								trkbuf->track_state_buf[trkbuf->nb_of_state].tracks[j].cur_parameffect = cptr->parameffect;
18748201da88SMatthias Ringwald 								if(cptr->sampinc)
18758201da88SMatthias Ringwald 									trkbuf->track_state_buf[trkbuf->nb_of_state].tracks[j].cur_period = (muint)(modctx->sampleticksconst / cptr->sampinc);
18768201da88SMatthias Ringwald 								else
18778201da88SMatthias Ringwald 									trkbuf->track_state_buf[trkbuf->nb_of_state].tracks[j].cur_period = 0;
1878a4cd9b30SMilanka Ringwald 								trkbuf->track_state_buf[trkbuf->nb_of_state].tracks[j].cur_volume = cptr->volume;
1879a4cd9b30SMilanka Ringwald 								trkbuf->track_state_buf[trkbuf->nb_of_state].tracks[j].instrument_number = (unsigned char)cptr->sampnum;
1880a4cd9b30SMilanka Ringwald 							}
1881a4cd9b30SMilanka Ringwald 						}
18828201da88SMatthias Ringwald #endif
1883a4cd9b30SMilanka Ringwald 					}
1884a4cd9b30SMilanka Ringwald 				}
1885a4cd9b30SMilanka Ringwald 
18868201da88SMatthias Ringwald #ifdef HXCMOD_STATE_REPORT_SUPPORT
1887a4cd9b30SMilanka Ringwald 				if( trkbuf && !state_remaining_steps )
1888a4cd9b30SMilanka Ringwald 				{
1889a4cd9b30SMilanka Ringwald 					state_remaining_steps = trkbuf->sample_step;
1890a4cd9b30SMilanka Ringwald 
1891a4cd9b30SMilanka Ringwald 					if(trkbuf->nb_of_state < trkbuf->nb_max_of_state)
1892a4cd9b30SMilanka Ringwald 						trkbuf->nb_of_state++;
1893a4cd9b30SMilanka Ringwald 				}
1894a4cd9b30SMilanka Ringwald 				else
18958201da88SMatthias Ringwald #endif
1896a4cd9b30SMilanka Ringwald 				{
1897a4cd9b30SMilanka Ringwald 					state_remaining_steps--;
1898a4cd9b30SMilanka Ringwald 				}
1899a4cd9b30SMilanka Ringwald 
19008201da88SMatthias Ringwald #ifdef HXCMOD_MONO_OUTPUT
19018201da88SMatthias Ringwald 
19028201da88SMatthias Ringwald 	#ifdef HXCMOD_OUTPUT_FILTER
19038201da88SMatthias Ringwald 				tr = (short)r;
19048201da88SMatthias Ringwald 
19058201da88SMatthias Ringwald 				if ( modctx->filter )
19068201da88SMatthias Ringwald 				{
19078201da88SMatthias Ringwald 					// Filter
19088201da88SMatthias Ringwald 					r = (r+lr)>>1;
19098201da88SMatthias Ringwald 				}
19108201da88SMatthias Ringwald 	#endif
19118201da88SMatthias Ringwald 
19128201da88SMatthias Ringwald 	#ifdef HXCMOD_CLIPPING_CHECK
19138201da88SMatthias Ringwald 				// Level limitation
19148201da88SMatthias Ringwald 				if( r > 32767 ) r = 32767;
19158201da88SMatthias Ringwald 				if( r < -32768 ) r = -32768;
19168201da88SMatthias Ringwald 	#endif
19178201da88SMatthias Ringwald 				// Store the final sample.
19188201da88SMatthias Ringwald 	#ifdef HXCMOD_8BITS_OUTPUT
19198201da88SMatthias Ringwald 
19208201da88SMatthias Ringwald 		#ifdef HXCMOD_UNSIGNED_OUTPUT
19218201da88SMatthias Ringwald 				*outbuffer++ = (r >> 8) + 127;
19228201da88SMatthias Ringwald 		#else
19238201da88SMatthias Ringwald 				*outbuffer++ = r >> 8;
19248201da88SMatthias Ringwald 		#endif
19258201da88SMatthias Ringwald 
19268201da88SMatthias Ringwald 	#else
19278201da88SMatthias Ringwald 
19288201da88SMatthias Ringwald 		#ifdef HXCMOD_UNSIGNED_OUTPUT
19298201da88SMatthias Ringwald 				*outbuffer++ = r + 32767;
19308201da88SMatthias Ringwald 		#else
19318201da88SMatthias Ringwald 				*outbuffer++ = r;
19328201da88SMatthias Ringwald 		#endif
19338201da88SMatthias Ringwald 
19348201da88SMatthias Ringwald 	#endif
19358201da88SMatthias Ringwald 
19368201da88SMatthias Ringwald 	#ifdef HXCMOD_OUTPUT_FILTER
19378201da88SMatthias Ringwald 				lr = tr;
19388201da88SMatthias Ringwald 	#endif
19398201da88SMatthias Ringwald 
19408201da88SMatthias Ringwald #else
19418201da88SMatthias Ringwald 
19428201da88SMatthias Ringwald 	#ifdef HXCMOD_OUTPUT_FILTER
1943a4cd9b30SMilanka Ringwald 				tl = (short)l;
1944a4cd9b30SMilanka Ringwald 				tr = (short)r;
1945a4cd9b30SMilanka Ringwald 
1946a4cd9b30SMilanka Ringwald 				if ( modctx->filter )
1947a4cd9b30SMilanka Ringwald 				{
1948a4cd9b30SMilanka Ringwald 					// Filter
1949a4cd9b30SMilanka Ringwald 					l = (l+ll)>>1;
1950a4cd9b30SMilanka Ringwald 					r = (r+lr)>>1;
1951a4cd9b30SMilanka Ringwald 				}
19528201da88SMatthias Ringwald 	#endif
1953a4cd9b30SMilanka Ringwald 
19548201da88SMatthias Ringwald 	#ifdef HXCMOD_OUTPUT_STEREO_MIX
1955a4cd9b30SMilanka Ringwald 				if ( modctx->stereo_separation == 1 )
1956a4cd9b30SMilanka Ringwald 				{
1957a4cd9b30SMilanka Ringwald 					// Left & Right Stereo panning
1958a4cd9b30SMilanka Ringwald 					l = (l+(r>>1));
1959a4cd9b30SMilanka Ringwald 					r = (r+(l>>1));
1960a4cd9b30SMilanka Ringwald 				}
19618201da88SMatthias Ringwald 	#endif
1962a4cd9b30SMilanka Ringwald 
19638201da88SMatthias Ringwald 	#ifdef HXCMOD_CLIPPING_CHECK
1964a4cd9b30SMilanka Ringwald 				// Level limitation
1965a4cd9b30SMilanka Ringwald 				if( l > 32767 ) l = 32767;
1966a4cd9b30SMilanka Ringwald 				if( l < -32768 ) l = -32768;
1967a4cd9b30SMilanka Ringwald 				if( r > 32767 ) r = 32767;
1968a4cd9b30SMilanka Ringwald 				if( r < -32768 ) r = -32768;
19698201da88SMatthias Ringwald 	#endif
1970a4cd9b30SMilanka Ringwald 				// Store the final sample.
1971a4cd9b30SMilanka Ringwald 
19728201da88SMatthias Ringwald 
19738201da88SMatthias Ringwald 	#ifdef HXCMOD_8BITS_OUTPUT
19748201da88SMatthias Ringwald 
19758201da88SMatthias Ringwald 		#ifdef HXCMOD_UNSIGNED_OUTPUT
19768201da88SMatthias Ringwald 				*outbuffer++ = ( l >> 8 ) + 127;
19778201da88SMatthias Ringwald 				*outbuffer++ = ( r >> 8 ) + 127;
19788201da88SMatthias Ringwald 		#else
19798201da88SMatthias Ringwald 				*outbuffer++ = l >> 8;
19808201da88SMatthias Ringwald 				*outbuffer++ = r >> 8;
19818201da88SMatthias Ringwald 		#endif
19828201da88SMatthias Ringwald 
19838201da88SMatthias Ringwald 	#else
19848201da88SMatthias Ringwald 
19858201da88SMatthias Ringwald 		#ifdef HXCMOD_UNSIGNED_OUTPUT
19868201da88SMatthias Ringwald 				*outbuffer++ = l + 32767;
19878201da88SMatthias Ringwald 				*outbuffer++ = r + 32767;
19888201da88SMatthias Ringwald 		#else
19898201da88SMatthias Ringwald 				*outbuffer++ = l;
19908201da88SMatthias Ringwald 				*outbuffer++ = r;
19918201da88SMatthias Ringwald 		#endif
19928201da88SMatthias Ringwald 
19938201da88SMatthias Ringwald 	#endif
19948201da88SMatthias Ringwald 
19958201da88SMatthias Ringwald 	#ifdef HXCMOD_OUTPUT_FILTER
1996a4cd9b30SMilanka Ringwald 				ll = tl;
1997a4cd9b30SMilanka Ringwald 				lr = tr;
19988201da88SMatthias Ringwald 	#endif
19998201da88SMatthias Ringwald 
20008201da88SMatthias Ringwald #endif // HXCMOD_MONO_OUTPUT
2001a4cd9b30SMilanka Ringwald 
2002a4cd9b30SMilanka Ringwald 			}
2003a4cd9b30SMilanka Ringwald 
20048201da88SMatthias Ringwald #ifdef HXCMOD_OUTPUT_FILTER
20058201da88SMatthias Ringwald 	#ifndef HXCMOD_MONO_OUTPUT
2006a4cd9b30SMilanka Ringwald 			modctx->last_l_sample = ll;
20078201da88SMatthias Ringwald 	#endif
2008a4cd9b30SMilanka Ringwald 			modctx->last_r_sample = lr;
20098201da88SMatthias Ringwald #endif
2010a4cd9b30SMilanka Ringwald 		}
2011a4cd9b30SMilanka Ringwald 		else
2012a4cd9b30SMilanka Ringwald 		{
2013a4cd9b30SMilanka Ringwald 			for (i = 0; i < nbsample; i++)
2014a4cd9b30SMilanka Ringwald 			{
2015a4cd9b30SMilanka Ringwald 				// Mod not loaded. Return blank buffer.
20168201da88SMatthias Ringwald #ifdef HXCMOD_MONO_OUTPUT
20178201da88SMatthias Ringwald 				outbuffer[i] = 0;
20188201da88SMatthias Ringwald #else
20198201da88SMatthias Ringwald 				*outbuffer++ = 0;
20208201da88SMatthias Ringwald 				*outbuffer++ = 0;
20218201da88SMatthias Ringwald #endif
2022a4cd9b30SMilanka Ringwald 			}
2023a4cd9b30SMilanka Ringwald 
20248201da88SMatthias Ringwald #ifdef HXCMOD_STATE_REPORT_SUPPORT
2025a4cd9b30SMilanka Ringwald 			if(trkbuf)
2026a4cd9b30SMilanka Ringwald 			{
2027a4cd9b30SMilanka Ringwald 				trkbuf->nb_of_state = 0;
2028a4cd9b30SMilanka Ringwald 				trkbuf->cur_rd_index = 0;
2029a4cd9b30SMilanka Ringwald 				trkbuf->name[0] = 0;
2030a4cd9b30SMilanka Ringwald 				memclear(trkbuf->track_state_buf,0,sizeof(tracker_state) * trkbuf->nb_max_of_state);
2031a4cd9b30SMilanka Ringwald 				memclear(trkbuf->instruments,0,sizeof(trkbuf->instruments));
2032a4cd9b30SMilanka Ringwald 			}
20338201da88SMatthias Ringwald #endif
2034a4cd9b30SMilanka Ringwald 		}
2035a4cd9b30SMilanka Ringwald 	}
2036a4cd9b30SMilanka Ringwald }
2037a4cd9b30SMilanka Ringwald 
2038a4cd9b30SMilanka Ringwald void hxcmod_unload( modcontext * modctx )
2039a4cd9b30SMilanka Ringwald {
2040a4cd9b30SMilanka Ringwald 	if(modctx)
2041a4cd9b30SMilanka Ringwald 	{
2042a4cd9b30SMilanka Ringwald 		memclear(&modctx->song,0,sizeof(modctx->song));
2043a4cd9b30SMilanka Ringwald 		memclear(&modctx->sampledata,0,sizeof(modctx->sampledata));
2044a4cd9b30SMilanka Ringwald 		memclear(&modctx->patterndata,0,sizeof(modctx->patterndata));
2045a4cd9b30SMilanka Ringwald 		modctx->tablepos = 0;
2046a4cd9b30SMilanka Ringwald 		modctx->patternpos = 0;
2047a4cd9b30SMilanka Ringwald 		modctx->patterndelay  = 0;
2048a4cd9b30SMilanka Ringwald 		modctx->jump_loop_effect = 0;
2049a4cd9b30SMilanka Ringwald 		modctx->bpm = 0;
2050a4cd9b30SMilanka Ringwald 		modctx->patternticks = 0;
2051a4cd9b30SMilanka Ringwald 		modctx->patterntickse = 0;
2052a4cd9b30SMilanka Ringwald 		modctx->patternticksaim = 0;
2053a4cd9b30SMilanka Ringwald 		modctx->sampleticksconst = 0;
2054a4cd9b30SMilanka Ringwald 
2055a4cd9b30SMilanka Ringwald 		memclear(modctx->channels,0,sizeof(modctx->channels));
2056a4cd9b30SMilanka Ringwald 
2057a4cd9b30SMilanka Ringwald 		modctx->number_of_channels = 0;
2058a4cd9b30SMilanka Ringwald 
2059a4cd9b30SMilanka Ringwald 		modctx->mod_loaded = 0;
2060a4cd9b30SMilanka Ringwald 
2061a4cd9b30SMilanka Ringwald 		modctx->last_r_sample = 0;
2062a4cd9b30SMilanka Ringwald 		modctx->last_l_sample = 0;
2063a4cd9b30SMilanka Ringwald 	}
2064a4cd9b30SMilanka Ringwald }
2065