1*a4cd9b30SMilanka Ringwald /////////////////////////////////////////////////////////////////////////////////// 2*a4cd9b30SMilanka Ringwald //-------------------------------------------------------------------------------// 3*a4cd9b30SMilanka Ringwald //-------------------------------------------------------------------------------// 4*a4cd9b30SMilanka Ringwald //-----------H----H--X----X-----CCCCC----22222----0000-----0000------11----------// 5*a4cd9b30SMilanka Ringwald //----------H----H----X-X-----C--------------2---0----0---0----0--1--1-----------// 6*a4cd9b30SMilanka Ringwald //---------HHHHHH-----X------C----------22222---0----0---0----0-----1------------// 7*a4cd9b30SMilanka Ringwald //--------H----H----X--X----C----------2-------0----0---0----0-----1-------------// 8*a4cd9b30SMilanka Ringwald //-------H----H---X-----X---CCCCC-----222222----0000-----0000----1111------------// 9*a4cd9b30SMilanka Ringwald //-------------------------------------------------------------------------------// 10*a4cd9b30SMilanka Ringwald //----------------------------------------------------- http://hxc2001.free.fr --// 11*a4cd9b30SMilanka Ringwald /////////////////////////////////////////////////////////////////////////////////// 12*a4cd9b30SMilanka Ringwald // File : hxcmod.c 13*a4cd9b30SMilanka Ringwald // Contains: a tiny mod player 14*a4cd9b30SMilanka Ringwald // 15*a4cd9b30SMilanka Ringwald // Written by: Jean Fran�ois DEL NERO 16*a4cd9b30SMilanka Ringwald // 17*a4cd9b30SMilanka Ringwald // You are free to do what you want with this code. 18*a4cd9b30SMilanka Ringwald // A credit is always appreciated if you include it into your prod :) 19*a4cd9b30SMilanka Ringwald // 20*a4cd9b30SMilanka Ringwald // This file include some parts of the Noisetracker/Soundtracker/Protracker 21*a4cd9b30SMilanka Ringwald // Module Format documentation written by Andrew Scott (Adrenalin Software) 22*a4cd9b30SMilanka Ringwald // (modformat.txt) 23*a4cd9b30SMilanka Ringwald // 24*a4cd9b30SMilanka Ringwald // The core (hxcmod.c/hxcmod.h) is designed to have the least external dependency. 25*a4cd9b30SMilanka Ringwald // So it should be usable on almost all OS and systems. 26*a4cd9b30SMilanka Ringwald // Please also note that no dynamic allocation is done into the HxCMOD core. 27*a4cd9b30SMilanka Ringwald // 28*a4cd9b30SMilanka Ringwald // Change History (most recent first): 29*a4cd9b30SMilanka Ringwald /////////////////////////////////////////////////////////////////////////////////// 30*a4cd9b30SMilanka Ringwald // HxCMOD Core API: 31*a4cd9b30SMilanka Ringwald // ------------------------------------------- 32*a4cd9b30SMilanka Ringwald // int hxcmod_init(modcontext * modctx) 33*a4cd9b30SMilanka Ringwald // 34*a4cd9b30SMilanka Ringwald // - Initialize the modcontext buffer. Must be called before doing anything else. 35*a4cd9b30SMilanka Ringwald // Return 1 if success. 0 in case of error. 36*a4cd9b30SMilanka Ringwald // ------------------------------------------- 37*a4cd9b30SMilanka Ringwald // int hxcmod_load( modcontext * modctx, void * mod_data, int mod_data_size ) 38*a4cd9b30SMilanka Ringwald // 39*a4cd9b30SMilanka Ringwald // - "Load" a MOD from memory (from "mod_data" with size "mod_data_size"). 40*a4cd9b30SMilanka Ringwald // Return 1 if success. 0 in case of error. 41*a4cd9b30SMilanka Ringwald // ------------------------------------------- 42*a4cd9b30SMilanka Ringwald // void hxcmod_fillbuffer( modcontext * modctx, unsigned short * outbuffer, unsigned long nbsample, tracker_buffer_state * trkbuf ) 43*a4cd9b30SMilanka Ringwald // 44*a4cd9b30SMilanka Ringwald // - Generate and return the next samples chunk to outbuffer. 45*a4cd9b30SMilanka Ringwald // nbsample specify the number of stereo 16bits samples you want. 46*a4cd9b30SMilanka Ringwald // The output format is signed 44100Hz 16-bit Stereo PCM samples. 47*a4cd9b30SMilanka Ringwald // The output buffer size in byte must be equal to ( nbsample * 2 * 2 ). 48*a4cd9b30SMilanka Ringwald // The optional trkbuf parameter can be used to get detailed status of the player. Put NULL/0 is unused. 49*a4cd9b30SMilanka Ringwald // ------------------------------------------- 50*a4cd9b30SMilanka Ringwald // void hxcmod_unload( modcontext * modctx ) 51*a4cd9b30SMilanka Ringwald // - "Unload" / clear the player status. 52*a4cd9b30SMilanka Ringwald // ------------------------------------------- 53*a4cd9b30SMilanka Ringwald /////////////////////////////////////////////////////////////////////////////////// 54*a4cd9b30SMilanka Ringwald 55*a4cd9b30SMilanka Ringwald #include "hxcmod.h" 56*a4cd9b30SMilanka Ringwald 57*a4cd9b30SMilanka Ringwald /////////////////////////////////////////////////////////////////////////////////// 58*a4cd9b30SMilanka Ringwald 59*a4cd9b30SMilanka Ringwald // Effects list 60*a4cd9b30SMilanka Ringwald #define EFFECT_ARPEGGIO 0x0 // Supported 61*a4cd9b30SMilanka Ringwald #define EFFECT_PORTAMENTO_UP 0x1 // Supported 62*a4cd9b30SMilanka Ringwald #define EFFECT_PORTAMENTO_DOWN 0x2 // Supported 63*a4cd9b30SMilanka Ringwald #define EFFECT_TONE_PORTAMENTO 0x3 // Supported 64*a4cd9b30SMilanka Ringwald #define EFFECT_VIBRATO 0x4 // Supported 65*a4cd9b30SMilanka Ringwald #define EFFECT_VOLSLIDE_TONEPORTA 0x5 // Supported 66*a4cd9b30SMilanka Ringwald #define EFFECT_VOLSLIDE_VIBRATO 0x6 // Supported 67*a4cd9b30SMilanka Ringwald #define EFFECT_VOLSLIDE_TREMOLO 0x7 // - TO BE DONE - 68*a4cd9b30SMilanka Ringwald #define EFFECT_SET_PANNING 0x8 // - TO BE DONE - 69*a4cd9b30SMilanka Ringwald #define EFFECT_SET_OFFSET 0x9 // Supported 70*a4cd9b30SMilanka Ringwald #define EFFECT_VOLUME_SLIDE 0xA // Supported 71*a4cd9b30SMilanka Ringwald #define EFFECT_JUMP_POSITION 0xB // Supported 72*a4cd9b30SMilanka Ringwald #define EFFECT_SET_VOLUME 0xC // Supported 73*a4cd9b30SMilanka Ringwald #define EFFECT_PATTERN_BREAK 0xD // Supported 74*a4cd9b30SMilanka Ringwald 75*a4cd9b30SMilanka Ringwald #define EFFECT_EXTENDED 0xE 76*a4cd9b30SMilanka Ringwald #define EFFECT_E_FINE_PORTA_UP 0x1 // Supported 77*a4cd9b30SMilanka Ringwald #define EFFECT_E_FINE_PORTA_DOWN 0x2 // Supported 78*a4cd9b30SMilanka Ringwald #define EFFECT_E_GLISSANDO_CTRL 0x3 // - TO BE DONE - 79*a4cd9b30SMilanka Ringwald #define EFFECT_E_VIBRATO_WAVEFORM 0x4 // - TO BE DONE - 80*a4cd9b30SMilanka Ringwald #define EFFECT_E_SET_FINETUNE 0x5 // - TO BE DONE - 81*a4cd9b30SMilanka Ringwald #define EFFECT_E_PATTERN_LOOP 0x6 // Supported 82*a4cd9b30SMilanka Ringwald #define EFFECT_E_TREMOLO_WAVEFORM 0x7 // - TO BE DONE - 83*a4cd9b30SMilanka Ringwald #define EFFECT_E_SET_PANNING_2 0x8 // - TO BE DONE - 84*a4cd9b30SMilanka Ringwald #define EFFECT_E_RETRIGGER_NOTE 0x9 // - TO BE DONE - 85*a4cd9b30SMilanka Ringwald #define EFFECT_E_FINE_VOLSLIDE_UP 0xA // Supported 86*a4cd9b30SMilanka Ringwald #define EFFECT_E_FINE_VOLSLIDE_DOWN 0xB // Supported 87*a4cd9b30SMilanka Ringwald #define EFFECT_E_NOTE_CUT 0xC // Supported 88*a4cd9b30SMilanka Ringwald #define EFFECT_E_NOTE_DELAY 0xD // - TO BE DONE - 89*a4cd9b30SMilanka Ringwald #define EFFECT_E_PATTERN_DELAY 0xE // Supported 90*a4cd9b30SMilanka Ringwald #define EFFECT_E_INVERT_LOOP 0xF // - TO BE DONE - 91*a4cd9b30SMilanka Ringwald #define EFFECT_SET_SPEED 0xF0 // Supported 92*a4cd9b30SMilanka Ringwald #define EFFECT_SET_TEMPO 0xF2 // Supported 93*a4cd9b30SMilanka Ringwald 94*a4cd9b30SMilanka Ringwald #define PERIOD_TABLE_LENGTH MAXNOTES 95*a4cd9b30SMilanka Ringwald #define FULL_PERIOD_TABLE_LENGTH ( PERIOD_TABLE_LENGTH * 8 ) 96*a4cd9b30SMilanka Ringwald 97*a4cd9b30SMilanka Ringwald static const short periodtable[]= 98*a4cd9b30SMilanka Ringwald { 99*a4cd9b30SMilanka Ringwald 27392, 25856, 24384, 23040, 21696, 20480, 19328, 18240, 17216, 16256, 15360, 14496, 100*a4cd9b30SMilanka Ringwald 13696, 12928, 12192, 11520, 10848, 10240, 9664, 9120, 8606, 8128, 7680, 7248, 101*a4cd9b30SMilanka Ringwald 6848, 6464, 6096, 5760, 5424, 5120, 4832, 4560, 4304, 4064, 3840, 3624, 102*a4cd9b30SMilanka Ringwald 3424, 3232, 3048, 2880, 2712, 2560, 2416, 2280, 2152, 2032, 1920, 1812, 103*a4cd9b30SMilanka Ringwald 1712, 1616, 1524, 1440, 1356, 1280, 1208, 1140, 1076, 1016, 960, 906, 104*a4cd9b30SMilanka Ringwald 856, 808, 762, 720, 678, 640, 604, 570, 538, 508, 480, 453, 105*a4cd9b30SMilanka Ringwald 428, 404, 381, 360, 339, 320, 302, 285, 269, 254, 240, 226, 106*a4cd9b30SMilanka Ringwald 214, 202, 190, 180, 170, 160, 151, 143, 135, 127, 120, 113, 107*a4cd9b30SMilanka Ringwald 107, 101, 95, 90, 85, 80, 75, 71, 67, 63, 60, 56, 108*a4cd9b30SMilanka Ringwald 53, 50, 47, 45, 42, 40, 37, 35, 33, 31, 30, 28, 109*a4cd9b30SMilanka Ringwald 27, 25, 24, 22, 21, 20, 19, 18, 17, 16, 15, 14, 110*a4cd9b30SMilanka Ringwald 13, 13, 12, 11, 11, 10, 9, 9, 8, 8, 7, 7 111*a4cd9b30SMilanka Ringwald }; 112*a4cd9b30SMilanka Ringwald 113*a4cd9b30SMilanka Ringwald static const short sintable[]={ 114*a4cd9b30SMilanka Ringwald 0, 24, 49, 74, 97, 120, 141,161, 115*a4cd9b30SMilanka Ringwald 180, 197, 212, 224, 235, 244, 250,253, 116*a4cd9b30SMilanka Ringwald 255, 253, 250, 244, 235, 224, 212,197, 117*a4cd9b30SMilanka Ringwald 180, 161, 141, 120, 97, 74, 49, 24 118*a4cd9b30SMilanka Ringwald }; 119*a4cd9b30SMilanka Ringwald 120*a4cd9b30SMilanka Ringwald typedef struct modtype_ 121*a4cd9b30SMilanka Ringwald { 122*a4cd9b30SMilanka Ringwald unsigned char signature[5]; 123*a4cd9b30SMilanka Ringwald int numberofchannels; 124*a4cd9b30SMilanka Ringwald }modtype; 125*a4cd9b30SMilanka Ringwald 126*a4cd9b30SMilanka Ringwald modtype modlist[]= 127*a4cd9b30SMilanka Ringwald { 128*a4cd9b30SMilanka Ringwald { "M!K!",4}, 129*a4cd9b30SMilanka Ringwald { "M.K.",4}, 130*a4cd9b30SMilanka Ringwald { "FLT4",4}, 131*a4cd9b30SMilanka Ringwald { "FLT8",8}, 132*a4cd9b30SMilanka Ringwald { "4CHN",4}, 133*a4cd9b30SMilanka Ringwald { "6CHN",6}, 134*a4cd9b30SMilanka Ringwald { "8CHN",8}, 135*a4cd9b30SMilanka Ringwald { "10CH",10}, 136*a4cd9b30SMilanka Ringwald { "12CH",12}, 137*a4cd9b30SMilanka Ringwald { "14CH",14}, 138*a4cd9b30SMilanka Ringwald { "16CH",16}, 139*a4cd9b30SMilanka Ringwald { "18CH",18}, 140*a4cd9b30SMilanka Ringwald { "20CH",20}, 141*a4cd9b30SMilanka Ringwald { "22CH",22}, 142*a4cd9b30SMilanka Ringwald { "24CH",24}, 143*a4cd9b30SMilanka Ringwald { "26CH",26}, 144*a4cd9b30SMilanka Ringwald { "28CH",28}, 145*a4cd9b30SMilanka Ringwald { "30CH",30}, 146*a4cd9b30SMilanka Ringwald { "32CH",32}, 147*a4cd9b30SMilanka Ringwald { "",0} 148*a4cd9b30SMilanka Ringwald }; 149*a4cd9b30SMilanka Ringwald 150*a4cd9b30SMilanka Ringwald /////////////////////////////////////////////////////////////////////////////////// 151*a4cd9b30SMilanka Ringwald 152*a4cd9b30SMilanka Ringwald static void memcopy( void * dest, void *source, unsigned long size ) 153*a4cd9b30SMilanka Ringwald { 154*a4cd9b30SMilanka Ringwald unsigned long i; 155*a4cd9b30SMilanka Ringwald unsigned char * d,*s; 156*a4cd9b30SMilanka Ringwald 157*a4cd9b30SMilanka Ringwald d=(unsigned char*)dest; 158*a4cd9b30SMilanka Ringwald s=(unsigned char*)source; 159*a4cd9b30SMilanka Ringwald for(i=0;i<size;i++) 160*a4cd9b30SMilanka Ringwald { 161*a4cd9b30SMilanka Ringwald d[i]=s[i]; 162*a4cd9b30SMilanka Ringwald } 163*a4cd9b30SMilanka Ringwald } 164*a4cd9b30SMilanka Ringwald 165*a4cd9b30SMilanka Ringwald static void memclear( void * dest, unsigned char value, unsigned long size ) 166*a4cd9b30SMilanka Ringwald { 167*a4cd9b30SMilanka Ringwald unsigned long i; 168*a4cd9b30SMilanka Ringwald unsigned char * d; 169*a4cd9b30SMilanka Ringwald 170*a4cd9b30SMilanka Ringwald d=(unsigned char*)dest; 171*a4cd9b30SMilanka Ringwald for(i=0;i<size;i++) 172*a4cd9b30SMilanka Ringwald { 173*a4cd9b30SMilanka Ringwald d[i]=value; 174*a4cd9b30SMilanka Ringwald } 175*a4cd9b30SMilanka Ringwald } 176*a4cd9b30SMilanka Ringwald 177*a4cd9b30SMilanka Ringwald static int memcompare( unsigned char * buf1, unsigned char * buf2, unsigned int size ) 178*a4cd9b30SMilanka Ringwald { 179*a4cd9b30SMilanka Ringwald unsigned int i; 180*a4cd9b30SMilanka Ringwald 181*a4cd9b30SMilanka Ringwald i = 0; 182*a4cd9b30SMilanka Ringwald 183*a4cd9b30SMilanka Ringwald while(i<size) 184*a4cd9b30SMilanka Ringwald { 185*a4cd9b30SMilanka Ringwald if(buf1[i] != buf2[i]) 186*a4cd9b30SMilanka Ringwald { 187*a4cd9b30SMilanka Ringwald return 0; 188*a4cd9b30SMilanka Ringwald } 189*a4cd9b30SMilanka Ringwald i++; 190*a4cd9b30SMilanka Ringwald } 191*a4cd9b30SMilanka Ringwald 192*a4cd9b30SMilanka Ringwald return 1; 193*a4cd9b30SMilanka Ringwald } 194*a4cd9b30SMilanka Ringwald 195*a4cd9b30SMilanka Ringwald static int getnote( modcontext * mod, unsigned short period, int finetune ) 196*a4cd9b30SMilanka Ringwald { 197*a4cd9b30SMilanka Ringwald int i; 198*a4cd9b30SMilanka Ringwald 199*a4cd9b30SMilanka Ringwald for(i = 0; i < FULL_PERIOD_TABLE_LENGTH; i++) 200*a4cd9b30SMilanka Ringwald { 201*a4cd9b30SMilanka Ringwald if(period >= mod->fullperiod[i]) 202*a4cd9b30SMilanka Ringwald { 203*a4cd9b30SMilanka Ringwald return i; 204*a4cd9b30SMilanka Ringwald } 205*a4cd9b30SMilanka Ringwald } 206*a4cd9b30SMilanka Ringwald 207*a4cd9b30SMilanka Ringwald return MAXNOTES; 208*a4cd9b30SMilanka Ringwald } 209*a4cd9b30SMilanka Ringwald 210*a4cd9b30SMilanka Ringwald static void worknote( note * nptr, channel * cptr,char t,modcontext * mod ) 211*a4cd9b30SMilanka Ringwald { 212*a4cd9b30SMilanka Ringwald muint sample, period, effect, operiod; 213*a4cd9b30SMilanka Ringwald muint curnote, arpnote; 214*a4cd9b30SMilanka Ringwald 215*a4cd9b30SMilanka Ringwald sample = (nptr->sampperiod & 0xF0) | (nptr->sampeffect >> 4); 216*a4cd9b30SMilanka Ringwald period = ((nptr->sampperiod & 0xF) << 8) | nptr->period; 217*a4cd9b30SMilanka Ringwald effect = ((nptr->sampeffect & 0xF) << 8) | nptr->effect; 218*a4cd9b30SMilanka Ringwald 219*a4cd9b30SMilanka Ringwald operiod = cptr->period; 220*a4cd9b30SMilanka Ringwald 221*a4cd9b30SMilanka Ringwald if ( period || sample ) 222*a4cd9b30SMilanka Ringwald { 223*a4cd9b30SMilanka Ringwald if( sample && sample<32 ) 224*a4cd9b30SMilanka Ringwald { 225*a4cd9b30SMilanka Ringwald cptr->sampnum = sample - 1; 226*a4cd9b30SMilanka Ringwald } 227*a4cd9b30SMilanka Ringwald 228*a4cd9b30SMilanka Ringwald if( period || sample ) 229*a4cd9b30SMilanka Ringwald { 230*a4cd9b30SMilanka Ringwald cptr->sampdata =(char *) mod->sampledata[cptr->sampnum]; 231*a4cd9b30SMilanka Ringwald cptr->length = mod->song.samples[cptr->sampnum].length; 232*a4cd9b30SMilanka Ringwald cptr->reppnt = mod->song.samples[cptr->sampnum].reppnt; 233*a4cd9b30SMilanka Ringwald cptr->replen = mod->song.samples[cptr->sampnum].replen; 234*a4cd9b30SMilanka Ringwald 235*a4cd9b30SMilanka Ringwald cptr->finetune = (mod->song.samples[cptr->sampnum].finetune)&0xF; 236*a4cd9b30SMilanka Ringwald 237*a4cd9b30SMilanka Ringwald if(effect>>8!=4 && effect>>8!=6) 238*a4cd9b30SMilanka Ringwald { 239*a4cd9b30SMilanka Ringwald cptr->vibraperiod=0; 240*a4cd9b30SMilanka Ringwald cptr->vibrapointeur=0; 241*a4cd9b30SMilanka Ringwald } 242*a4cd9b30SMilanka Ringwald } 243*a4cd9b30SMilanka Ringwald 244*a4cd9b30SMilanka Ringwald if( (sample != 0) && ( (effect>>8) != EFFECT_VOLSLIDE_TONEPORTA ) ) 245*a4cd9b30SMilanka Ringwald { 246*a4cd9b30SMilanka Ringwald cptr->volume = mod->song.samples[cptr->sampnum].volume; 247*a4cd9b30SMilanka Ringwald cptr->volumeslide = 0; 248*a4cd9b30SMilanka Ringwald } 249*a4cd9b30SMilanka Ringwald 250*a4cd9b30SMilanka Ringwald if( ( (effect>>8) != EFFECT_TONE_PORTAMENTO && (effect>>8)!=EFFECT_VOLSLIDE_TONEPORTA) ) 251*a4cd9b30SMilanka Ringwald { 252*a4cd9b30SMilanka Ringwald if (period!=0) 253*a4cd9b30SMilanka Ringwald cptr->samppos = 0; 254*a4cd9b30SMilanka Ringwald } 255*a4cd9b30SMilanka Ringwald 256*a4cd9b30SMilanka Ringwald cptr->decalperiod=0; 257*a4cd9b30SMilanka Ringwald if( period ) 258*a4cd9b30SMilanka Ringwald { 259*a4cd9b30SMilanka Ringwald if(cptr->finetune) 260*a4cd9b30SMilanka Ringwald { 261*a4cd9b30SMilanka Ringwald if( cptr->finetune <= 7 ) 262*a4cd9b30SMilanka Ringwald { 263*a4cd9b30SMilanka Ringwald period = mod->fullperiod[getnote(mod,period,0) + cptr->finetune]; 264*a4cd9b30SMilanka Ringwald } 265*a4cd9b30SMilanka Ringwald else 266*a4cd9b30SMilanka Ringwald { 267*a4cd9b30SMilanka Ringwald period = mod->fullperiod[getnote(mod,period,0) - (16 - (cptr->finetune)) ]; 268*a4cd9b30SMilanka Ringwald } 269*a4cd9b30SMilanka Ringwald } 270*a4cd9b30SMilanka Ringwald 271*a4cd9b30SMilanka Ringwald cptr->period = period; 272*a4cd9b30SMilanka Ringwald } 273*a4cd9b30SMilanka Ringwald 274*a4cd9b30SMilanka Ringwald } 275*a4cd9b30SMilanka Ringwald 276*a4cd9b30SMilanka Ringwald cptr->effect = 0; 277*a4cd9b30SMilanka Ringwald cptr->parameffect = 0; 278*a4cd9b30SMilanka Ringwald cptr->effect_code = effect; 279*a4cd9b30SMilanka Ringwald 280*a4cd9b30SMilanka Ringwald switch (effect >> 8) 281*a4cd9b30SMilanka Ringwald { 282*a4cd9b30SMilanka Ringwald case EFFECT_ARPEGGIO: 283*a4cd9b30SMilanka Ringwald /* 284*a4cd9b30SMilanka Ringwald [0]: Arpeggio 285*a4cd9b30SMilanka Ringwald Where [0][x][y] means "play note, note+x semitones, note+y 286*a4cd9b30SMilanka Ringwald semitones, then return to original note". The fluctuations are 287*a4cd9b30SMilanka Ringwald carried out evenly spaced in one pattern division. They are usually 288*a4cd9b30SMilanka Ringwald used to simulate chords, but this doesn't work too well. They are 289*a4cd9b30SMilanka Ringwald also used to produce heavy vibrato. A major chord is when x=4, y=7. 290*a4cd9b30SMilanka Ringwald A minor chord is when x=3, y=7. 291*a4cd9b30SMilanka Ringwald */ 292*a4cd9b30SMilanka Ringwald 293*a4cd9b30SMilanka Ringwald if(effect&0xff) 294*a4cd9b30SMilanka Ringwald { 295*a4cd9b30SMilanka Ringwald cptr->effect = EFFECT_ARPEGGIO; 296*a4cd9b30SMilanka Ringwald cptr->parameffect = effect&0xff; 297*a4cd9b30SMilanka Ringwald 298*a4cd9b30SMilanka Ringwald cptr->ArpIndex = 0; 299*a4cd9b30SMilanka Ringwald 300*a4cd9b30SMilanka Ringwald curnote = getnote(mod,cptr->period,cptr->finetune); 301*a4cd9b30SMilanka Ringwald 302*a4cd9b30SMilanka Ringwald cptr->Arpperiods[0] = cptr->period; 303*a4cd9b30SMilanka Ringwald 304*a4cd9b30SMilanka Ringwald arpnote = curnote + (((cptr->parameffect>>4)&0xF)*8); 305*a4cd9b30SMilanka Ringwald if( arpnote >= FULL_PERIOD_TABLE_LENGTH ) 306*a4cd9b30SMilanka Ringwald arpnote = FULL_PERIOD_TABLE_LENGTH - 1; 307*a4cd9b30SMilanka Ringwald 308*a4cd9b30SMilanka Ringwald cptr->Arpperiods[1] = mod->fullperiod[arpnote]; 309*a4cd9b30SMilanka Ringwald 310*a4cd9b30SMilanka Ringwald arpnote = curnote + (((cptr->parameffect)&0xF)*8); 311*a4cd9b30SMilanka Ringwald if( arpnote >= FULL_PERIOD_TABLE_LENGTH ) 312*a4cd9b30SMilanka Ringwald arpnote = FULL_PERIOD_TABLE_LENGTH - 1; 313*a4cd9b30SMilanka Ringwald 314*a4cd9b30SMilanka Ringwald cptr->Arpperiods[2] = mod->fullperiod[arpnote]; 315*a4cd9b30SMilanka Ringwald } 316*a4cd9b30SMilanka Ringwald break; 317*a4cd9b30SMilanka Ringwald 318*a4cd9b30SMilanka Ringwald case EFFECT_PORTAMENTO_UP: 319*a4cd9b30SMilanka Ringwald /* 320*a4cd9b30SMilanka Ringwald [1]: Slide up 321*a4cd9b30SMilanka Ringwald Where [1][x][y] means "smoothly decrease the period of current 322*a4cd9b30SMilanka Ringwald sample by x*16+y after each tick in the division". The 323*a4cd9b30SMilanka Ringwald ticks/division are set with the 'set speed' effect (see below). If 324*a4cd9b30SMilanka Ringwald the period of the note being played is z, then the final period 325*a4cd9b30SMilanka Ringwald will be z - (x*16 + y)*(ticks - 1). As the slide rate depends on 326*a4cd9b30SMilanka Ringwald the speed, changing the speed will change the slide. You cannot 327*a4cd9b30SMilanka Ringwald slide beyond the note B3 (period 113). 328*a4cd9b30SMilanka Ringwald */ 329*a4cd9b30SMilanka Ringwald 330*a4cd9b30SMilanka Ringwald cptr->effect = EFFECT_PORTAMENTO_UP; 331*a4cd9b30SMilanka Ringwald cptr->parameffect = effect&0xff; 332*a4cd9b30SMilanka Ringwald break; 333*a4cd9b30SMilanka Ringwald 334*a4cd9b30SMilanka Ringwald case EFFECT_PORTAMENTO_DOWN: 335*a4cd9b30SMilanka Ringwald /* 336*a4cd9b30SMilanka Ringwald [2]: Slide down 337*a4cd9b30SMilanka Ringwald Where [2][x][y] means "smoothly increase the period of current 338*a4cd9b30SMilanka Ringwald sample by x*16+y after each tick in the division". Similar to [1], 339*a4cd9b30SMilanka Ringwald but lowers the pitch. You cannot slide beyond the note C1 (period 340*a4cd9b30SMilanka Ringwald 856). 341*a4cd9b30SMilanka Ringwald */ 342*a4cd9b30SMilanka Ringwald 343*a4cd9b30SMilanka Ringwald cptr->effect = EFFECT_PORTAMENTO_DOWN; 344*a4cd9b30SMilanka Ringwald cptr->parameffect = effect&0xff; 345*a4cd9b30SMilanka Ringwald break; 346*a4cd9b30SMilanka Ringwald 347*a4cd9b30SMilanka Ringwald case EFFECT_TONE_PORTAMENTO: 348*a4cd9b30SMilanka Ringwald /* 349*a4cd9b30SMilanka Ringwald [3]: Slide to note 350*a4cd9b30SMilanka Ringwald Where [3][x][y] means "smoothly change the period of current sample 351*a4cd9b30SMilanka Ringwald by x*16+y after each tick in the division, never sliding beyond 352*a4cd9b30SMilanka Ringwald current period". The period-length in this channel's division is a 353*a4cd9b30SMilanka Ringwald parameter to this effect, and hence is not played. Sliding to a 354*a4cd9b30SMilanka Ringwald note is similar to effects [1] and [2], but the slide will not go 355*a4cd9b30SMilanka Ringwald beyond the given period, and the direction is implied by that 356*a4cd9b30SMilanka Ringwald period. If x and y are both 0, then the old slide will continue. 357*a4cd9b30SMilanka Ringwald */ 358*a4cd9b30SMilanka Ringwald 359*a4cd9b30SMilanka Ringwald cptr->effect = EFFECT_TONE_PORTAMENTO; 360*a4cd9b30SMilanka Ringwald if( (effect&0xff) != 0 ) 361*a4cd9b30SMilanka Ringwald { 362*a4cd9b30SMilanka Ringwald cptr->portaspeed = (short)(effect&0xff); 363*a4cd9b30SMilanka Ringwald } 364*a4cd9b30SMilanka Ringwald 365*a4cd9b30SMilanka Ringwald if(period!=0) 366*a4cd9b30SMilanka Ringwald { 367*a4cd9b30SMilanka Ringwald cptr->portaperiod = period; 368*a4cd9b30SMilanka Ringwald cptr->period = operiod; 369*a4cd9b30SMilanka Ringwald } 370*a4cd9b30SMilanka Ringwald break; 371*a4cd9b30SMilanka Ringwald 372*a4cd9b30SMilanka Ringwald case EFFECT_VIBRATO: 373*a4cd9b30SMilanka Ringwald /* 374*a4cd9b30SMilanka Ringwald [4]: Vibrato 375*a4cd9b30SMilanka Ringwald Where [4][x][y] means "oscillate the sample pitch using a 376*a4cd9b30SMilanka Ringwald particular waveform with amplitude y/16 semitones, such that (x * 377*a4cd9b30SMilanka Ringwald ticks)/64 cycles occur in the division". The waveform is set using 378*a4cd9b30SMilanka Ringwald effect [14][4]. By placing vibrato effects on consecutive 379*a4cd9b30SMilanka Ringwald divisions, the vibrato effect can be maintained. If either x or y 380*a4cd9b30SMilanka Ringwald are 0, then the old vibrato values will be used. 381*a4cd9b30SMilanka Ringwald */ 382*a4cd9b30SMilanka Ringwald 383*a4cd9b30SMilanka Ringwald cptr->effect = EFFECT_VIBRATO; 384*a4cd9b30SMilanka Ringwald if( ( effect & 0x0F ) != 0 ) // Depth continue or change ? 385*a4cd9b30SMilanka Ringwald cptr->vibraparam = (cptr->vibraparam & 0xF0) | ( effect & 0x0F ); 386*a4cd9b30SMilanka Ringwald if( ( effect & 0xF0 ) != 0 ) // Speed continue or change ? 387*a4cd9b30SMilanka Ringwald cptr->vibraparam = (cptr->vibraparam & 0x0F) | ( effect & 0xF0 ); 388*a4cd9b30SMilanka Ringwald 389*a4cd9b30SMilanka Ringwald break; 390*a4cd9b30SMilanka Ringwald 391*a4cd9b30SMilanka Ringwald case EFFECT_VOLSLIDE_TONEPORTA: 392*a4cd9b30SMilanka Ringwald /* 393*a4cd9b30SMilanka Ringwald [5]: Continue 'Slide to note', but also do Volume slide 394*a4cd9b30SMilanka Ringwald Where [5][x][y] means "either slide the volume up x*(ticks - 1) or 395*a4cd9b30SMilanka Ringwald slide the volume down y*(ticks - 1), at the same time as continuing 396*a4cd9b30SMilanka Ringwald the last 'Slide to note'". It is illegal for both x and y to be 397*a4cd9b30SMilanka Ringwald non-zero. You cannot slide outside the volume range 0..64. The 398*a4cd9b30SMilanka Ringwald period-length in this channel's division is a parameter to this 399*a4cd9b30SMilanka Ringwald effect, and hence is not played. 400*a4cd9b30SMilanka Ringwald */ 401*a4cd9b30SMilanka Ringwald 402*a4cd9b30SMilanka Ringwald if( period != 0 ) 403*a4cd9b30SMilanka Ringwald { 404*a4cd9b30SMilanka Ringwald cptr->portaperiod = period; 405*a4cd9b30SMilanka Ringwald cptr->period = operiod; 406*a4cd9b30SMilanka Ringwald } 407*a4cd9b30SMilanka Ringwald 408*a4cd9b30SMilanka Ringwald cptr->effect = EFFECT_VOLSLIDE_TONEPORTA; 409*a4cd9b30SMilanka Ringwald if( ( effect & 0xFF ) != 0 ) 410*a4cd9b30SMilanka Ringwald cptr->volumeslide = ( effect & 0xFF ); 411*a4cd9b30SMilanka Ringwald 412*a4cd9b30SMilanka Ringwald break; 413*a4cd9b30SMilanka Ringwald 414*a4cd9b30SMilanka Ringwald case EFFECT_VOLSLIDE_VIBRATO: 415*a4cd9b30SMilanka Ringwald /* 416*a4cd9b30SMilanka Ringwald [6]: Continue 'Vibrato', but also do Volume slide 417*a4cd9b30SMilanka Ringwald Where [6][x][y] means "either slide the volume up x*(ticks - 1) or 418*a4cd9b30SMilanka Ringwald slide the volume down y*(ticks - 1), at the same time as continuing 419*a4cd9b30SMilanka Ringwald the last 'Vibrato'". It is illegal for both x and y to be non-zero. 420*a4cd9b30SMilanka Ringwald You cannot slide outside the volume range 0..64. 421*a4cd9b30SMilanka Ringwald */ 422*a4cd9b30SMilanka Ringwald 423*a4cd9b30SMilanka Ringwald cptr->effect = EFFECT_VOLSLIDE_VIBRATO; 424*a4cd9b30SMilanka Ringwald if( (effect & 0xFF) != 0 ) 425*a4cd9b30SMilanka Ringwald cptr->volumeslide = (effect & 0xFF); 426*a4cd9b30SMilanka Ringwald break; 427*a4cd9b30SMilanka Ringwald 428*a4cd9b30SMilanka Ringwald case EFFECT_SET_OFFSET: 429*a4cd9b30SMilanka Ringwald /* 430*a4cd9b30SMilanka Ringwald [9]: Set sample offset 431*a4cd9b30SMilanka Ringwald Where [9][x][y] means "play the sample from offset x*4096 + y*256". 432*a4cd9b30SMilanka Ringwald The offset is measured in words. If no sample is given, yet one is 433*a4cd9b30SMilanka Ringwald still playing on this channel, it should be retriggered to the new 434*a4cd9b30SMilanka Ringwald offset using the current volume. 435*a4cd9b30SMilanka Ringwald */ 436*a4cd9b30SMilanka Ringwald 437*a4cd9b30SMilanka Ringwald cptr->samppos = ((effect>>4) * 4096) + ((effect&0xF)*256); 438*a4cd9b30SMilanka Ringwald 439*a4cd9b30SMilanka Ringwald break; 440*a4cd9b30SMilanka Ringwald 441*a4cd9b30SMilanka Ringwald case EFFECT_VOLUME_SLIDE: 442*a4cd9b30SMilanka Ringwald /* 443*a4cd9b30SMilanka Ringwald [10]: Volume slide 444*a4cd9b30SMilanka Ringwald Where [10][x][y] means "either slide the volume up x*(ticks - 1) or 445*a4cd9b30SMilanka Ringwald slide the volume down y*(ticks - 1)". If both x and y are non-zero, 446*a4cd9b30SMilanka Ringwald then the y value is ignored (assumed to be 0). You cannot slide 447*a4cd9b30SMilanka Ringwald outside the volume range 0..64. 448*a4cd9b30SMilanka Ringwald */ 449*a4cd9b30SMilanka Ringwald 450*a4cd9b30SMilanka Ringwald cptr->effect = EFFECT_VOLUME_SLIDE; 451*a4cd9b30SMilanka Ringwald cptr->volumeslide = (effect & 0xFF); 452*a4cd9b30SMilanka Ringwald break; 453*a4cd9b30SMilanka Ringwald 454*a4cd9b30SMilanka Ringwald case EFFECT_JUMP_POSITION: 455*a4cd9b30SMilanka Ringwald /* 456*a4cd9b30SMilanka Ringwald [11]: Position Jump 457*a4cd9b30SMilanka Ringwald Where [11][x][y] means "stop the pattern after this division, and 458*a4cd9b30SMilanka Ringwald continue the song at song-position x*16+y". This shifts the 459*a4cd9b30SMilanka Ringwald 'pattern-cursor' in the pattern table (see above). Legal values for 460*a4cd9b30SMilanka Ringwald x*16+y are from 0 to 127. 461*a4cd9b30SMilanka Ringwald */ 462*a4cd9b30SMilanka Ringwald 463*a4cd9b30SMilanka Ringwald mod->tablepos = (effect & 0xFF); 464*a4cd9b30SMilanka Ringwald if(mod->tablepos >= mod->song.length) 465*a4cd9b30SMilanka Ringwald mod->tablepos = 0; 466*a4cd9b30SMilanka Ringwald mod->patternpos = 0; 467*a4cd9b30SMilanka Ringwald mod->jump_loop_effect = 1; 468*a4cd9b30SMilanka Ringwald 469*a4cd9b30SMilanka Ringwald break; 470*a4cd9b30SMilanka Ringwald 471*a4cd9b30SMilanka Ringwald case EFFECT_SET_VOLUME: 472*a4cd9b30SMilanka Ringwald /* 473*a4cd9b30SMilanka Ringwald [12]: Set volume 474*a4cd9b30SMilanka Ringwald Where [12][x][y] means "set current sample's volume to x*16+y". 475*a4cd9b30SMilanka Ringwald Legal volumes are 0..64. 476*a4cd9b30SMilanka Ringwald */ 477*a4cd9b30SMilanka Ringwald 478*a4cd9b30SMilanka Ringwald cptr->volume = (effect & 0xFF); 479*a4cd9b30SMilanka Ringwald break; 480*a4cd9b30SMilanka Ringwald 481*a4cd9b30SMilanka Ringwald case EFFECT_PATTERN_BREAK: 482*a4cd9b30SMilanka Ringwald /* 483*a4cd9b30SMilanka Ringwald [13]: Pattern Break 484*a4cd9b30SMilanka Ringwald Where [13][x][y] means "stop the pattern after this division, and 485*a4cd9b30SMilanka Ringwald continue the song at the next pattern at division x*10+y" (the 10 486*a4cd9b30SMilanka Ringwald is not a typo). Legal divisions are from 0 to 63 (note Protracker 487*a4cd9b30SMilanka Ringwald exception above). 488*a4cd9b30SMilanka Ringwald */ 489*a4cd9b30SMilanka Ringwald 490*a4cd9b30SMilanka Ringwald mod->patternpos = ( ((effect>>4)&0xF)*10 + (effect&0xF) ) * mod->number_of_channels; 491*a4cd9b30SMilanka Ringwald mod->jump_loop_effect = 1; 492*a4cd9b30SMilanka Ringwald mod->tablepos++; 493*a4cd9b30SMilanka Ringwald if(mod->tablepos >= mod->song.length) 494*a4cd9b30SMilanka Ringwald mod->tablepos = 0; 495*a4cd9b30SMilanka Ringwald 496*a4cd9b30SMilanka Ringwald break; 497*a4cd9b30SMilanka Ringwald 498*a4cd9b30SMilanka Ringwald case EFFECT_EXTENDED: 499*a4cd9b30SMilanka Ringwald switch( (effect>>4) & 0xF ) 500*a4cd9b30SMilanka Ringwald { 501*a4cd9b30SMilanka Ringwald case EFFECT_E_FINE_PORTA_UP: 502*a4cd9b30SMilanka Ringwald /* 503*a4cd9b30SMilanka Ringwald [14][1]: Fineslide up 504*a4cd9b30SMilanka Ringwald Where [14][1][x] means "decrement the period of the current sample 505*a4cd9b30SMilanka Ringwald by x". The incrementing takes place at the beginning of the 506*a4cd9b30SMilanka Ringwald division, and hence there is no actual sliding. You cannot slide 507*a4cd9b30SMilanka Ringwald beyond the note B3 (period 113). 508*a4cd9b30SMilanka Ringwald */ 509*a4cd9b30SMilanka Ringwald 510*a4cd9b30SMilanka Ringwald cptr->period -= (effect & 0xF); 511*a4cd9b30SMilanka Ringwald if( cptr->period < 113 ) 512*a4cd9b30SMilanka Ringwald cptr->period = 113; 513*a4cd9b30SMilanka Ringwald break; 514*a4cd9b30SMilanka Ringwald 515*a4cd9b30SMilanka Ringwald case EFFECT_E_FINE_PORTA_DOWN: 516*a4cd9b30SMilanka Ringwald /* 517*a4cd9b30SMilanka Ringwald [14][2]: Fineslide down 518*a4cd9b30SMilanka Ringwald Where [14][2][x] means "increment the period of the current sample 519*a4cd9b30SMilanka Ringwald by x". Similar to [14][1] but shifts the pitch down. You cannot 520*a4cd9b30SMilanka Ringwald slide beyond the note C1 (period 856). 521*a4cd9b30SMilanka Ringwald */ 522*a4cd9b30SMilanka Ringwald 523*a4cd9b30SMilanka Ringwald cptr->period += (effect & 0xF); 524*a4cd9b30SMilanka Ringwald if( cptr->period > 856 ) 525*a4cd9b30SMilanka Ringwald cptr->period = 856; 526*a4cd9b30SMilanka Ringwald break; 527*a4cd9b30SMilanka Ringwald 528*a4cd9b30SMilanka Ringwald case EFFECT_E_FINE_VOLSLIDE_UP: 529*a4cd9b30SMilanka Ringwald /* 530*a4cd9b30SMilanka Ringwald [14][10]: Fine volume slide up 531*a4cd9b30SMilanka Ringwald Where [14][10][x] means "increment the volume of the current sample 532*a4cd9b30SMilanka Ringwald by x". The incrementing takes place at the beginning of the 533*a4cd9b30SMilanka Ringwald division, and hence there is no sliding. You cannot slide beyond 534*a4cd9b30SMilanka Ringwald volume 64. 535*a4cd9b30SMilanka Ringwald */ 536*a4cd9b30SMilanka Ringwald 537*a4cd9b30SMilanka Ringwald cptr->volume += (effect & 0xF); 538*a4cd9b30SMilanka Ringwald if( cptr->volume>64 ) 539*a4cd9b30SMilanka Ringwald cptr->volume = 64; 540*a4cd9b30SMilanka Ringwald break; 541*a4cd9b30SMilanka Ringwald 542*a4cd9b30SMilanka Ringwald case EFFECT_E_FINE_VOLSLIDE_DOWN: 543*a4cd9b30SMilanka Ringwald /* 544*a4cd9b30SMilanka Ringwald [14][11]: Fine volume slide down 545*a4cd9b30SMilanka Ringwald Where [14][11][x] means "decrement the volume of the current sample 546*a4cd9b30SMilanka Ringwald by x". Similar to [14][10] but lowers volume. You cannot slide 547*a4cd9b30SMilanka Ringwald beyond volume 0. 548*a4cd9b30SMilanka Ringwald */ 549*a4cd9b30SMilanka Ringwald 550*a4cd9b30SMilanka Ringwald cptr->volume -= (effect & 0xF); 551*a4cd9b30SMilanka Ringwald if( cptr->volume > 200 ) 552*a4cd9b30SMilanka Ringwald cptr->volume = 0; 553*a4cd9b30SMilanka Ringwald break; 554*a4cd9b30SMilanka Ringwald 555*a4cd9b30SMilanka Ringwald case EFFECT_E_PATTERN_LOOP: 556*a4cd9b30SMilanka Ringwald /* 557*a4cd9b30SMilanka Ringwald [14][6]: Loop pattern 558*a4cd9b30SMilanka Ringwald Where [14][6][x] means "set the start of a loop to this division if 559*a4cd9b30SMilanka Ringwald x is 0, otherwise after this division, jump back to the start of a 560*a4cd9b30SMilanka Ringwald loop and play it another x times before continuing". If the start 561*a4cd9b30SMilanka Ringwald of the loop was not set, it will default to the start of the 562*a4cd9b30SMilanka Ringwald current pattern. Hence 'loop pattern' cannot be performed across 563*a4cd9b30SMilanka Ringwald multiple patterns. Note that loops do not support nesting, and you 564*a4cd9b30SMilanka Ringwald may generate an infinite loop if you try to nest 'loop pattern's. 565*a4cd9b30SMilanka Ringwald */ 566*a4cd9b30SMilanka Ringwald 567*a4cd9b30SMilanka Ringwald if( effect & 0xF ) 568*a4cd9b30SMilanka Ringwald { 569*a4cd9b30SMilanka Ringwald if( cptr->patternloopcnt ) 570*a4cd9b30SMilanka Ringwald { 571*a4cd9b30SMilanka Ringwald cptr->patternloopcnt--; 572*a4cd9b30SMilanka Ringwald if( cptr->patternloopcnt ) 573*a4cd9b30SMilanka Ringwald { 574*a4cd9b30SMilanka Ringwald mod->patternpos = cptr->patternloopstartpoint; 575*a4cd9b30SMilanka Ringwald mod->jump_loop_effect = 1; 576*a4cd9b30SMilanka Ringwald } 577*a4cd9b30SMilanka Ringwald else 578*a4cd9b30SMilanka Ringwald { 579*a4cd9b30SMilanka Ringwald cptr->patternloopstartpoint = mod->patternpos ; 580*a4cd9b30SMilanka Ringwald } 581*a4cd9b30SMilanka Ringwald } 582*a4cd9b30SMilanka Ringwald else 583*a4cd9b30SMilanka Ringwald { 584*a4cd9b30SMilanka Ringwald cptr->patternloopcnt = (effect & 0xF); 585*a4cd9b30SMilanka Ringwald mod->patternpos = cptr->patternloopstartpoint; 586*a4cd9b30SMilanka Ringwald mod->jump_loop_effect = 1; 587*a4cd9b30SMilanka Ringwald } 588*a4cd9b30SMilanka Ringwald } 589*a4cd9b30SMilanka Ringwald else // Start point 590*a4cd9b30SMilanka Ringwald { 591*a4cd9b30SMilanka Ringwald cptr->patternloopstartpoint = mod->patternpos; 592*a4cd9b30SMilanka Ringwald } 593*a4cd9b30SMilanka Ringwald 594*a4cd9b30SMilanka Ringwald break; 595*a4cd9b30SMilanka Ringwald 596*a4cd9b30SMilanka Ringwald case EFFECT_E_PATTERN_DELAY: 597*a4cd9b30SMilanka Ringwald /* 598*a4cd9b30SMilanka Ringwald [14][14]: Delay pattern 599*a4cd9b30SMilanka Ringwald Where [14][14][x] means "after this division there will be a delay 600*a4cd9b30SMilanka Ringwald equivalent to the time taken to play x divisions after which the 601*a4cd9b30SMilanka Ringwald pattern will be resumed". The delay only relates to the 602*a4cd9b30SMilanka Ringwald interpreting of new divisions, and all effects and previous notes 603*a4cd9b30SMilanka Ringwald continue during delay. 604*a4cd9b30SMilanka Ringwald */ 605*a4cd9b30SMilanka Ringwald 606*a4cd9b30SMilanka Ringwald mod->patterndelay = (effect & 0xF); 607*a4cd9b30SMilanka Ringwald break; 608*a4cd9b30SMilanka Ringwald 609*a4cd9b30SMilanka Ringwald case EFFECT_E_NOTE_CUT: 610*a4cd9b30SMilanka Ringwald /* 611*a4cd9b30SMilanka Ringwald [14][12]: Cut sample 612*a4cd9b30SMilanka Ringwald Where [14][12][x] means "after the current sample has been played 613*a4cd9b30SMilanka Ringwald for x ticks in this division, its volume will be set to 0". This 614*a4cd9b30SMilanka Ringwald implies that if x is 0, then you will not hear any of the sample. 615*a4cd9b30SMilanka Ringwald If you wish to insert "silence" in a pattern, it is better to use a 616*a4cd9b30SMilanka Ringwald "silence"-sample (see above) due to the lack of proper support for 617*a4cd9b30SMilanka Ringwald this effect. 618*a4cd9b30SMilanka Ringwald */ 619*a4cd9b30SMilanka Ringwald cptr->effect = EFFECT_E_NOTE_CUT; 620*a4cd9b30SMilanka Ringwald cptr->cut_param = (effect & 0xF); 621*a4cd9b30SMilanka Ringwald if(!cptr->cut_param) 622*a4cd9b30SMilanka Ringwald cptr->volume = 0; 623*a4cd9b30SMilanka Ringwald break; 624*a4cd9b30SMilanka Ringwald 625*a4cd9b30SMilanka Ringwald default: 626*a4cd9b30SMilanka Ringwald 627*a4cd9b30SMilanka Ringwald break; 628*a4cd9b30SMilanka Ringwald } 629*a4cd9b30SMilanka Ringwald break; 630*a4cd9b30SMilanka Ringwald 631*a4cd9b30SMilanka Ringwald case 0xF: 632*a4cd9b30SMilanka Ringwald /* 633*a4cd9b30SMilanka Ringwald [15]: Set speed 634*a4cd9b30SMilanka Ringwald Where [15][x][y] means "set speed to x*16+y". Though it is nowhere 635*a4cd9b30SMilanka Ringwald near that simple. Let z = x*16+y. Depending on what values z takes, 636*a4cd9b30SMilanka Ringwald different units of speed are set, there being two: ticks/division 637*a4cd9b30SMilanka Ringwald and beats/minute (though this one is only a label and not strictly 638*a4cd9b30SMilanka Ringwald true). If z=0, then what should technically happen is that the 639*a4cd9b30SMilanka Ringwald module stops, but in practice it is treated as if z=1, because 640*a4cd9b30SMilanka Ringwald there is already a method for stopping the module (running out of 641*a4cd9b30SMilanka Ringwald patterns). If z<=32, then it means "set ticks/division to z" 642*a4cd9b30SMilanka Ringwald otherwise it means "set beats/minute to z" (convention says that 643*a4cd9b30SMilanka Ringwald this should read "If z<32.." but there are some composers out there 644*a4cd9b30SMilanka Ringwald that defy conventions). Default values are 6 ticks/division, and 645*a4cd9b30SMilanka Ringwald 125 beats/minute (4 divisions = 1 beat). The beats/minute tag is 646*a4cd9b30SMilanka Ringwald only meaningful for 6 ticks/division. To get a more accurate view 647*a4cd9b30SMilanka Ringwald of how things work, use the following formula: 648*a4cd9b30SMilanka Ringwald 24 * beats/minute 649*a4cd9b30SMilanka Ringwald divisions/minute = ----------------- 650*a4cd9b30SMilanka Ringwald ticks/division 651*a4cd9b30SMilanka Ringwald Hence divisions/minute range from 24.75 to 6120, eg. to get a value 652*a4cd9b30SMilanka Ringwald of 2000 divisions/minute use 3 ticks/division and 250 beats/minute. 653*a4cd9b30SMilanka Ringwald If multiple "set speed" effects are performed in a single division, 654*a4cd9b30SMilanka Ringwald the ones on higher-numbered channels take precedence over the ones 655*a4cd9b30SMilanka Ringwald on lower-numbered channels. This effect has a large number of 656*a4cd9b30SMilanka Ringwald different implementations, but the one described here has the 657*a4cd9b30SMilanka Ringwald widest usage. 658*a4cd9b30SMilanka Ringwald */ 659*a4cd9b30SMilanka Ringwald 660*a4cd9b30SMilanka Ringwald if( (effect&0xFF) < 0x21 ) 661*a4cd9b30SMilanka Ringwald { 662*a4cd9b30SMilanka Ringwald if( effect&0xFF ) 663*a4cd9b30SMilanka Ringwald { 664*a4cd9b30SMilanka Ringwald mod->song.speed = effect&0xFF; 665*a4cd9b30SMilanka Ringwald mod->patternticksaim = (long)mod->song.speed * ((mod->playrate * 5 ) / (((long)2 * (long)mod->bpm))); 666*a4cd9b30SMilanka Ringwald } 667*a4cd9b30SMilanka Ringwald } 668*a4cd9b30SMilanka Ringwald 669*a4cd9b30SMilanka Ringwald if( (effect&0xFF) >= 0x21 ) 670*a4cd9b30SMilanka Ringwald { 671*a4cd9b30SMilanka Ringwald /// HZ = 2 * BPM / 5 672*a4cd9b30SMilanka Ringwald mod->bpm = effect&0xFF; 673*a4cd9b30SMilanka Ringwald mod->patternticksaim = (long)mod->song.speed * ((mod->playrate * 5 ) / (((long)2 * (long)mod->bpm))); 674*a4cd9b30SMilanka Ringwald } 675*a4cd9b30SMilanka Ringwald 676*a4cd9b30SMilanka Ringwald break; 677*a4cd9b30SMilanka Ringwald 678*a4cd9b30SMilanka Ringwald default: 679*a4cd9b30SMilanka Ringwald // Unsupported effect 680*a4cd9b30SMilanka Ringwald break; 681*a4cd9b30SMilanka Ringwald 682*a4cd9b30SMilanka Ringwald } 683*a4cd9b30SMilanka Ringwald 684*a4cd9b30SMilanka Ringwald } 685*a4cd9b30SMilanka Ringwald 686*a4cd9b30SMilanka Ringwald static void workeffect( note * nptr, channel * cptr ) 687*a4cd9b30SMilanka Ringwald { 688*a4cd9b30SMilanka Ringwald switch(cptr->effect) 689*a4cd9b30SMilanka Ringwald { 690*a4cd9b30SMilanka Ringwald case EFFECT_ARPEGGIO: 691*a4cd9b30SMilanka Ringwald 692*a4cd9b30SMilanka Ringwald if( cptr->parameffect ) 693*a4cd9b30SMilanka Ringwald { 694*a4cd9b30SMilanka Ringwald cptr->decalperiod = cptr->period - cptr->Arpperiods[cptr->ArpIndex]; 695*a4cd9b30SMilanka Ringwald 696*a4cd9b30SMilanka Ringwald cptr->ArpIndex++; 697*a4cd9b30SMilanka Ringwald if( cptr->ArpIndex>2 ) 698*a4cd9b30SMilanka Ringwald cptr->ArpIndex = 0; 699*a4cd9b30SMilanka Ringwald } 700*a4cd9b30SMilanka Ringwald break; 701*a4cd9b30SMilanka Ringwald 702*a4cd9b30SMilanka Ringwald case EFFECT_PORTAMENTO_UP: 703*a4cd9b30SMilanka Ringwald 704*a4cd9b30SMilanka Ringwald if(cptr->period) 705*a4cd9b30SMilanka Ringwald { 706*a4cd9b30SMilanka Ringwald cptr->period -= cptr->parameffect; 707*a4cd9b30SMilanka Ringwald 708*a4cd9b30SMilanka Ringwald if( cptr->period < 113 || cptr->period > 20000 ) 709*a4cd9b30SMilanka Ringwald cptr->period = 113; 710*a4cd9b30SMilanka Ringwald } 711*a4cd9b30SMilanka Ringwald 712*a4cd9b30SMilanka Ringwald break; 713*a4cd9b30SMilanka Ringwald 714*a4cd9b30SMilanka Ringwald case EFFECT_PORTAMENTO_DOWN: 715*a4cd9b30SMilanka Ringwald 716*a4cd9b30SMilanka Ringwald if(cptr->period) 717*a4cd9b30SMilanka Ringwald { 718*a4cd9b30SMilanka Ringwald cptr->period += cptr->parameffect; 719*a4cd9b30SMilanka Ringwald 720*a4cd9b30SMilanka Ringwald if( cptr->period > 20000 ) 721*a4cd9b30SMilanka Ringwald cptr->period = 20000; 722*a4cd9b30SMilanka Ringwald } 723*a4cd9b30SMilanka Ringwald 724*a4cd9b30SMilanka Ringwald break; 725*a4cd9b30SMilanka Ringwald 726*a4cd9b30SMilanka Ringwald case EFFECT_VOLSLIDE_TONEPORTA: 727*a4cd9b30SMilanka Ringwald case EFFECT_TONE_PORTAMENTO: 728*a4cd9b30SMilanka Ringwald 729*a4cd9b30SMilanka Ringwald if( cptr->period && ( cptr->period != cptr->portaperiod ) && cptr->portaperiod ) 730*a4cd9b30SMilanka Ringwald { 731*a4cd9b30SMilanka Ringwald if( cptr->period > cptr->portaperiod ) 732*a4cd9b30SMilanka Ringwald { 733*a4cd9b30SMilanka Ringwald if( cptr->period - cptr->portaperiod >= cptr->portaspeed ) 734*a4cd9b30SMilanka Ringwald { 735*a4cd9b30SMilanka Ringwald cptr->period -= cptr->portaspeed; 736*a4cd9b30SMilanka Ringwald } 737*a4cd9b30SMilanka Ringwald else 738*a4cd9b30SMilanka Ringwald { 739*a4cd9b30SMilanka Ringwald cptr->period = cptr->portaperiod; 740*a4cd9b30SMilanka Ringwald } 741*a4cd9b30SMilanka Ringwald } 742*a4cd9b30SMilanka Ringwald else 743*a4cd9b30SMilanka Ringwald { 744*a4cd9b30SMilanka Ringwald if( cptr->portaperiod - cptr->period >= cptr->portaspeed ) 745*a4cd9b30SMilanka Ringwald { 746*a4cd9b30SMilanka Ringwald cptr->period += cptr->portaspeed; 747*a4cd9b30SMilanka Ringwald } 748*a4cd9b30SMilanka Ringwald else 749*a4cd9b30SMilanka Ringwald { 750*a4cd9b30SMilanka Ringwald cptr->period = cptr->portaperiod; 751*a4cd9b30SMilanka Ringwald } 752*a4cd9b30SMilanka Ringwald } 753*a4cd9b30SMilanka Ringwald 754*a4cd9b30SMilanka Ringwald if( cptr->period == cptr->portaperiod ) 755*a4cd9b30SMilanka Ringwald { 756*a4cd9b30SMilanka Ringwald // If the slide is over, don't let it to be retriggered. 757*a4cd9b30SMilanka Ringwald cptr->portaperiod = 0; 758*a4cd9b30SMilanka Ringwald } 759*a4cd9b30SMilanka Ringwald } 760*a4cd9b30SMilanka Ringwald 761*a4cd9b30SMilanka Ringwald if( cptr->effect == EFFECT_VOLSLIDE_TONEPORTA ) 762*a4cd9b30SMilanka Ringwald { 763*a4cd9b30SMilanka Ringwald if( cptr->volumeslide > 0x0F ) 764*a4cd9b30SMilanka Ringwald { 765*a4cd9b30SMilanka Ringwald cptr->volume = cptr->volume + (cptr->volumeslide>>4); 766*a4cd9b30SMilanka Ringwald 767*a4cd9b30SMilanka Ringwald if(cptr->volume>63) 768*a4cd9b30SMilanka Ringwald cptr->volume = 63; 769*a4cd9b30SMilanka Ringwald } 770*a4cd9b30SMilanka Ringwald else 771*a4cd9b30SMilanka Ringwald { 772*a4cd9b30SMilanka Ringwald cptr->volume = cptr->volume - (cptr->volumeslide); 773*a4cd9b30SMilanka Ringwald 774*a4cd9b30SMilanka Ringwald if(cptr->volume>63) 775*a4cd9b30SMilanka Ringwald cptr->volume=0; 776*a4cd9b30SMilanka Ringwald } 777*a4cd9b30SMilanka Ringwald } 778*a4cd9b30SMilanka Ringwald break; 779*a4cd9b30SMilanka Ringwald 780*a4cd9b30SMilanka Ringwald case EFFECT_VOLSLIDE_VIBRATO: 781*a4cd9b30SMilanka Ringwald case EFFECT_VIBRATO: 782*a4cd9b30SMilanka Ringwald 783*a4cd9b30SMilanka Ringwald cptr->vibraperiod = ( (cptr->vibraparam&0xF) * sintable[cptr->vibrapointeur&0x1F] )>>7; 784*a4cd9b30SMilanka Ringwald 785*a4cd9b30SMilanka Ringwald if( cptr->vibrapointeur > 31 ) 786*a4cd9b30SMilanka Ringwald cptr->vibraperiod = -cptr->vibraperiod; 787*a4cd9b30SMilanka Ringwald 788*a4cd9b30SMilanka Ringwald cptr->vibrapointeur = (cptr->vibrapointeur+(((cptr->vibraparam>>4))&0xf)) & 0x3F; 789*a4cd9b30SMilanka Ringwald 790*a4cd9b30SMilanka Ringwald if( cptr->effect == EFFECT_VOLSLIDE_VIBRATO ) 791*a4cd9b30SMilanka Ringwald { 792*a4cd9b30SMilanka Ringwald if( cptr->volumeslide > 0xF ) 793*a4cd9b30SMilanka Ringwald { 794*a4cd9b30SMilanka Ringwald cptr->volume = cptr->volume+(cptr->volumeslide>>4); 795*a4cd9b30SMilanka Ringwald 796*a4cd9b30SMilanka Ringwald if( cptr->volume > 64 ) 797*a4cd9b30SMilanka Ringwald cptr->volume = 64; 798*a4cd9b30SMilanka Ringwald } 799*a4cd9b30SMilanka Ringwald else 800*a4cd9b30SMilanka Ringwald { 801*a4cd9b30SMilanka Ringwald cptr->volume = cptr->volume - cptr->volumeslide; 802*a4cd9b30SMilanka Ringwald 803*a4cd9b30SMilanka Ringwald if( cptr->volume > 64 ) 804*a4cd9b30SMilanka Ringwald cptr->volume = 0; 805*a4cd9b30SMilanka Ringwald } 806*a4cd9b30SMilanka Ringwald } 807*a4cd9b30SMilanka Ringwald 808*a4cd9b30SMilanka Ringwald break; 809*a4cd9b30SMilanka Ringwald 810*a4cd9b30SMilanka Ringwald case EFFECT_VOLUME_SLIDE: 811*a4cd9b30SMilanka Ringwald 812*a4cd9b30SMilanka Ringwald if( cptr->volumeslide > 0xF ) 813*a4cd9b30SMilanka Ringwald { 814*a4cd9b30SMilanka Ringwald cptr->volume += (cptr->volumeslide>>4); 815*a4cd9b30SMilanka Ringwald 816*a4cd9b30SMilanka Ringwald if( cptr->volume > 64 ) 817*a4cd9b30SMilanka Ringwald cptr->volume = 64; 818*a4cd9b30SMilanka Ringwald } 819*a4cd9b30SMilanka Ringwald else 820*a4cd9b30SMilanka Ringwald { 821*a4cd9b30SMilanka Ringwald cptr->volume -= (cptr->volumeslide&0xf); 822*a4cd9b30SMilanka Ringwald 823*a4cd9b30SMilanka Ringwald if( cptr->volume > 64 ) 824*a4cd9b30SMilanka Ringwald cptr->volume = 0; 825*a4cd9b30SMilanka Ringwald } 826*a4cd9b30SMilanka Ringwald break; 827*a4cd9b30SMilanka Ringwald 828*a4cd9b30SMilanka Ringwald case EFFECT_E_NOTE_CUT: 829*a4cd9b30SMilanka Ringwald if(cptr->cut_param) 830*a4cd9b30SMilanka Ringwald cptr->cut_param--; 831*a4cd9b30SMilanka Ringwald 832*a4cd9b30SMilanka Ringwald if(!cptr->cut_param) 833*a4cd9b30SMilanka Ringwald cptr->volume = 0; 834*a4cd9b30SMilanka Ringwald break; 835*a4cd9b30SMilanka Ringwald 836*a4cd9b30SMilanka Ringwald default: 837*a4cd9b30SMilanka Ringwald break; 838*a4cd9b30SMilanka Ringwald 839*a4cd9b30SMilanka Ringwald } 840*a4cd9b30SMilanka Ringwald 841*a4cd9b30SMilanka Ringwald } 842*a4cd9b30SMilanka Ringwald 843*a4cd9b30SMilanka Ringwald /////////////////////////////////////////////////////////////////////////////////// 844*a4cd9b30SMilanka Ringwald int hxcmod_init(modcontext * modctx) 845*a4cd9b30SMilanka Ringwald { 846*a4cd9b30SMilanka Ringwald muint i,j; 847*a4cd9b30SMilanka Ringwald 848*a4cd9b30SMilanka Ringwald if( modctx ) 849*a4cd9b30SMilanka Ringwald { 850*a4cd9b30SMilanka Ringwald memclear(modctx,0,sizeof(modcontext)); 851*a4cd9b30SMilanka Ringwald modctx->playrate = 44100; 852*a4cd9b30SMilanka Ringwald modctx->stereo = 1; 853*a4cd9b30SMilanka Ringwald modctx->stereo_separation = 1; 854*a4cd9b30SMilanka Ringwald modctx->bits = 16; 855*a4cd9b30SMilanka Ringwald modctx->filter = 1; 856*a4cd9b30SMilanka Ringwald 857*a4cd9b30SMilanka Ringwald for(i=0;i<PERIOD_TABLE_LENGTH - 1;i++) 858*a4cd9b30SMilanka Ringwald { 859*a4cd9b30SMilanka Ringwald for(j=0;j<8;j++) 860*a4cd9b30SMilanka Ringwald { 861*a4cd9b30SMilanka Ringwald modctx->fullperiod[(i*8) + j] = periodtable[i] - ((( periodtable[i] - periodtable[i+1] ) / 8) * j); 862*a4cd9b30SMilanka Ringwald } 863*a4cd9b30SMilanka Ringwald } 864*a4cd9b30SMilanka Ringwald 865*a4cd9b30SMilanka Ringwald return 1; 866*a4cd9b30SMilanka Ringwald } 867*a4cd9b30SMilanka Ringwald 868*a4cd9b30SMilanka Ringwald return 0; 869*a4cd9b30SMilanka Ringwald } 870*a4cd9b30SMilanka Ringwald 871*a4cd9b30SMilanka Ringwald int hxcmod_setcfg(modcontext * modctx, int samplerate, int bits, int stereo, int stereo_separation, int filter) 872*a4cd9b30SMilanka Ringwald { 873*a4cd9b30SMilanka Ringwald if( modctx ) 874*a4cd9b30SMilanka Ringwald { 875*a4cd9b30SMilanka Ringwald modctx->playrate = samplerate; 876*a4cd9b30SMilanka Ringwald 877*a4cd9b30SMilanka Ringwald if( stereo ) 878*a4cd9b30SMilanka Ringwald modctx->stereo = 1; 879*a4cd9b30SMilanka Ringwald else 880*a4cd9b30SMilanka Ringwald modctx->stereo = 0; 881*a4cd9b30SMilanka Ringwald 882*a4cd9b30SMilanka Ringwald if(stereo_separation < 4) 883*a4cd9b30SMilanka Ringwald { 884*a4cd9b30SMilanka Ringwald modctx->stereo_separation = stereo_separation; 885*a4cd9b30SMilanka Ringwald } 886*a4cd9b30SMilanka Ringwald 887*a4cd9b30SMilanka Ringwald if( bits == 8 || bits == 16 ) 888*a4cd9b30SMilanka Ringwald { 889*a4cd9b30SMilanka Ringwald modctx->bits = bits; 890*a4cd9b30SMilanka Ringwald } 891*a4cd9b30SMilanka Ringwald 892*a4cd9b30SMilanka Ringwald if( filter ) 893*a4cd9b30SMilanka Ringwald modctx->filter = 1; 894*a4cd9b30SMilanka Ringwald else 895*a4cd9b30SMilanka Ringwald modctx->filter = 0; 896*a4cd9b30SMilanka Ringwald 897*a4cd9b30SMilanka Ringwald return 1; 898*a4cd9b30SMilanka Ringwald } 899*a4cd9b30SMilanka Ringwald 900*a4cd9b30SMilanka Ringwald return 0; 901*a4cd9b30SMilanka Ringwald } 902*a4cd9b30SMilanka Ringwald 903*a4cd9b30SMilanka Ringwald int hxcmod_load( modcontext * modctx, void * mod_data, int mod_data_size ) 904*a4cd9b30SMilanka Ringwald { 905*a4cd9b30SMilanka Ringwald muint i, max; 906*a4cd9b30SMilanka Ringwald unsigned short t; 907*a4cd9b30SMilanka Ringwald sample *sptr; 908*a4cd9b30SMilanka Ringwald unsigned char * modmemory,* endmodmemory; 909*a4cd9b30SMilanka Ringwald 910*a4cd9b30SMilanka Ringwald modmemory = (unsigned char *)mod_data; 911*a4cd9b30SMilanka Ringwald endmodmemory = modmemory + mod_data_size; 912*a4cd9b30SMilanka Ringwald 913*a4cd9b30SMilanka Ringwald if(modmemory) 914*a4cd9b30SMilanka Ringwald { 915*a4cd9b30SMilanka Ringwald if( modctx ) 916*a4cd9b30SMilanka Ringwald { 917*a4cd9b30SMilanka Ringwald memcopy(&(modctx->song.title),modmemory,1084); 918*a4cd9b30SMilanka Ringwald 919*a4cd9b30SMilanka Ringwald i = 0; 920*a4cd9b30SMilanka Ringwald modctx->number_of_channels = 0; 921*a4cd9b30SMilanka Ringwald while(modlist[i].numberofchannels) 922*a4cd9b30SMilanka Ringwald { 923*a4cd9b30SMilanka Ringwald if(memcompare(modctx->song.signature,modlist[i].signature,4)) 924*a4cd9b30SMilanka Ringwald { 925*a4cd9b30SMilanka Ringwald modctx->number_of_channels = modlist[i].numberofchannels; 926*a4cd9b30SMilanka Ringwald } 927*a4cd9b30SMilanka Ringwald 928*a4cd9b30SMilanka Ringwald i++; 929*a4cd9b30SMilanka Ringwald } 930*a4cd9b30SMilanka Ringwald 931*a4cd9b30SMilanka Ringwald if( !modctx->number_of_channels ) 932*a4cd9b30SMilanka Ringwald { 933*a4cd9b30SMilanka Ringwald // 15 Samples modules support 934*a4cd9b30SMilanka Ringwald // Shift the whole datas to make it look likes a standard 4 channels mod. 935*a4cd9b30SMilanka Ringwald memcopy(&(modctx->song.signature), "M.K.", 4); 936*a4cd9b30SMilanka Ringwald memcopy(&(modctx->song.length), &(modctx->song.samples[15]), 130); 937*a4cd9b30SMilanka Ringwald memclear(&(modctx->song.samples[15]), 0, 480); 938*a4cd9b30SMilanka Ringwald modmemory += 600; 939*a4cd9b30SMilanka Ringwald modctx->number_of_channels = 4; 940*a4cd9b30SMilanka Ringwald } 941*a4cd9b30SMilanka Ringwald else 942*a4cd9b30SMilanka Ringwald { 943*a4cd9b30SMilanka Ringwald modmemory += 1084; 944*a4cd9b30SMilanka Ringwald } 945*a4cd9b30SMilanka Ringwald 946*a4cd9b30SMilanka Ringwald if( modmemory >= endmodmemory ) 947*a4cd9b30SMilanka Ringwald return 0; // End passed ? - Probably a bad file ! 948*a4cd9b30SMilanka Ringwald 949*a4cd9b30SMilanka Ringwald // Patterns loading 950*a4cd9b30SMilanka Ringwald for (i = max = 0; i < 128; i++) 951*a4cd9b30SMilanka Ringwald { 952*a4cd9b30SMilanka Ringwald while (max <= modctx->song.patterntable[i]) 953*a4cd9b30SMilanka Ringwald { 954*a4cd9b30SMilanka Ringwald modctx->patterndata[max] = (note*)modmemory; 955*a4cd9b30SMilanka Ringwald modmemory += (256*modctx->number_of_channels); 956*a4cd9b30SMilanka Ringwald max++; 957*a4cd9b30SMilanka Ringwald 958*a4cd9b30SMilanka Ringwald if( modmemory >= endmodmemory ) 959*a4cd9b30SMilanka Ringwald return 0; // End passed ? - Probably a bad file ! 960*a4cd9b30SMilanka Ringwald } 961*a4cd9b30SMilanka Ringwald } 962*a4cd9b30SMilanka Ringwald 963*a4cd9b30SMilanka Ringwald for (i = 0; i < 31; i++) 964*a4cd9b30SMilanka Ringwald modctx->sampledata[i]=0; 965*a4cd9b30SMilanka Ringwald 966*a4cd9b30SMilanka Ringwald // Samples loading 967*a4cd9b30SMilanka Ringwald for (i = 0, sptr = modctx->song.samples; i <31; i++, sptr++) 968*a4cd9b30SMilanka Ringwald { 969*a4cd9b30SMilanka Ringwald t= (sptr->length &0xFF00)>>8 | (sptr->length &0xFF)<<8; 970*a4cd9b30SMilanka Ringwald sptr->length = t*2; 971*a4cd9b30SMilanka Ringwald 972*a4cd9b30SMilanka Ringwald t= (sptr->reppnt &0xFF00)>>8 | (sptr->reppnt &0xFF)<<8; 973*a4cd9b30SMilanka Ringwald sptr->reppnt = t*2; 974*a4cd9b30SMilanka Ringwald 975*a4cd9b30SMilanka Ringwald t= (sptr->replen &0xFF00)>>8 | (sptr->replen &0xFF)<<8; 976*a4cd9b30SMilanka Ringwald sptr->replen = t*2; 977*a4cd9b30SMilanka Ringwald 978*a4cd9b30SMilanka Ringwald 979*a4cd9b30SMilanka Ringwald if (sptr->length == 0) continue; 980*a4cd9b30SMilanka Ringwald 981*a4cd9b30SMilanka Ringwald modctx->sampledata[i] = (char*)modmemory; 982*a4cd9b30SMilanka Ringwald modmemory += sptr->length; 983*a4cd9b30SMilanka Ringwald 984*a4cd9b30SMilanka Ringwald if (sptr->replen + sptr->reppnt > sptr->length) 985*a4cd9b30SMilanka Ringwald sptr->replen = sptr->length - sptr->reppnt; 986*a4cd9b30SMilanka Ringwald 987*a4cd9b30SMilanka Ringwald if( modmemory > endmodmemory ) 988*a4cd9b30SMilanka Ringwald return 0; // End passed ? - Probably a bad file ! 989*a4cd9b30SMilanka Ringwald } 990*a4cd9b30SMilanka Ringwald 991*a4cd9b30SMilanka Ringwald // States init 992*a4cd9b30SMilanka Ringwald 993*a4cd9b30SMilanka Ringwald modctx->tablepos = 0; 994*a4cd9b30SMilanka Ringwald modctx->patternpos = 0; 995*a4cd9b30SMilanka Ringwald modctx->song.speed = 6; 996*a4cd9b30SMilanka Ringwald modctx->bpm = 125; 997*a4cd9b30SMilanka Ringwald modctx->samplenb = 0; 998*a4cd9b30SMilanka Ringwald 999*a4cd9b30SMilanka Ringwald modctx->patternticks = (((long)modctx->song.speed * modctx->playrate * 5)/ (2 * modctx->bpm)) + 1; 1000*a4cd9b30SMilanka Ringwald modctx->patternticksaim = ((long)modctx->song.speed * modctx->playrate * 5) / (2 * modctx->bpm); 1001*a4cd9b30SMilanka Ringwald 1002*a4cd9b30SMilanka Ringwald modctx->sampleticksconst = 3546894UL / modctx->playrate; //8448*428/playrate; 1003*a4cd9b30SMilanka Ringwald 1004*a4cd9b30SMilanka Ringwald for(i=0; i < modctx->number_of_channels; i++) 1005*a4cd9b30SMilanka Ringwald { 1006*a4cd9b30SMilanka Ringwald modctx->channels[i].volume = 0; 1007*a4cd9b30SMilanka Ringwald modctx->channels[i].period = 0; 1008*a4cd9b30SMilanka Ringwald } 1009*a4cd9b30SMilanka Ringwald 1010*a4cd9b30SMilanka Ringwald modctx->mod_loaded = 1; 1011*a4cd9b30SMilanka Ringwald 1012*a4cd9b30SMilanka Ringwald return 1; 1013*a4cd9b30SMilanka Ringwald } 1014*a4cd9b30SMilanka Ringwald } 1015*a4cd9b30SMilanka Ringwald 1016*a4cd9b30SMilanka Ringwald return 0; 1017*a4cd9b30SMilanka Ringwald } 1018*a4cd9b30SMilanka Ringwald 1019*a4cd9b30SMilanka Ringwald void hxcmod_fillbuffer( modcontext * modctx, unsigned short * outbuffer, unsigned long nbsample, tracker_buffer_state * trkbuf ) 1020*a4cd9b30SMilanka Ringwald { 1021*a4cd9b30SMilanka Ringwald unsigned long i, j; 1022*a4cd9b30SMilanka Ringwald unsigned long k; 1023*a4cd9b30SMilanka Ringwald unsigned char c; 1024*a4cd9b30SMilanka Ringwald unsigned int state_remaining_steps; 1025*a4cd9b30SMilanka Ringwald int l,r; 1026*a4cd9b30SMilanka Ringwald int ll,lr; 1027*a4cd9b30SMilanka Ringwald int tl,tr; 1028*a4cd9b30SMilanka Ringwald short finalperiod; 1029*a4cd9b30SMilanka Ringwald note *nptr; 1030*a4cd9b30SMilanka Ringwald channel *cptr; 1031*a4cd9b30SMilanka Ringwald 1032*a4cd9b30SMilanka Ringwald if( modctx && outbuffer ) 1033*a4cd9b30SMilanka Ringwald { 1034*a4cd9b30SMilanka Ringwald if(modctx->mod_loaded) 1035*a4cd9b30SMilanka Ringwald { 1036*a4cd9b30SMilanka Ringwald state_remaining_steps = 0; 1037*a4cd9b30SMilanka Ringwald 1038*a4cd9b30SMilanka Ringwald if( trkbuf ) 1039*a4cd9b30SMilanka Ringwald { 1040*a4cd9b30SMilanka Ringwald trkbuf->cur_rd_index = 0; 1041*a4cd9b30SMilanka Ringwald 1042*a4cd9b30SMilanka Ringwald memcopy(trkbuf->name,modctx->song.title,sizeof(modctx->song.title)); 1043*a4cd9b30SMilanka Ringwald 1044*a4cd9b30SMilanka Ringwald for(i=0;i<31;i++) 1045*a4cd9b30SMilanka Ringwald { 1046*a4cd9b30SMilanka Ringwald memcopy(trkbuf->instruments[i].name,modctx->song.samples[i].name,sizeof(trkbuf->instruments[i].name)); 1047*a4cd9b30SMilanka Ringwald } 1048*a4cd9b30SMilanka Ringwald } 1049*a4cd9b30SMilanka Ringwald 1050*a4cd9b30SMilanka Ringwald ll = modctx->last_l_sample; 1051*a4cd9b30SMilanka Ringwald lr = modctx->last_r_sample; 1052*a4cd9b30SMilanka Ringwald 1053*a4cd9b30SMilanka Ringwald for (i = 0; i < nbsample; i++) 1054*a4cd9b30SMilanka Ringwald { 1055*a4cd9b30SMilanka Ringwald //--------------------------------------- 1056*a4cd9b30SMilanka Ringwald if( modctx->patternticks++ > modctx->patternticksaim ) 1057*a4cd9b30SMilanka Ringwald { 1058*a4cd9b30SMilanka Ringwald if( !modctx->patterndelay ) 1059*a4cd9b30SMilanka Ringwald { 1060*a4cd9b30SMilanka Ringwald nptr = modctx->patterndata[modctx->song.patterntable[modctx->tablepos]]; 1061*a4cd9b30SMilanka Ringwald nptr = nptr + modctx->patternpos; 1062*a4cd9b30SMilanka Ringwald cptr = modctx->channels; 1063*a4cd9b30SMilanka Ringwald 1064*a4cd9b30SMilanka Ringwald modctx->patternticks = 0; 1065*a4cd9b30SMilanka Ringwald modctx->patterntickse = 0; 1066*a4cd9b30SMilanka Ringwald 1067*a4cd9b30SMilanka Ringwald for(c=0;c<modctx->number_of_channels;c++) 1068*a4cd9b30SMilanka Ringwald { 1069*a4cd9b30SMilanka Ringwald worknote((note*)(nptr+c), (channel*)(cptr+c),(char)(c+1),modctx); 1070*a4cd9b30SMilanka Ringwald } 1071*a4cd9b30SMilanka Ringwald 1072*a4cd9b30SMilanka Ringwald if( !modctx->jump_loop_effect ) 1073*a4cd9b30SMilanka Ringwald modctx->patternpos += modctx->number_of_channels; 1074*a4cd9b30SMilanka Ringwald else 1075*a4cd9b30SMilanka Ringwald modctx->jump_loop_effect = 0; 1076*a4cd9b30SMilanka Ringwald 1077*a4cd9b30SMilanka Ringwald if( modctx->patternpos == 64*modctx->number_of_channels ) 1078*a4cd9b30SMilanka Ringwald { 1079*a4cd9b30SMilanka Ringwald modctx->tablepos++; 1080*a4cd9b30SMilanka Ringwald modctx->patternpos = 0; 1081*a4cd9b30SMilanka Ringwald if(modctx->tablepos >= modctx->song.length) 1082*a4cd9b30SMilanka Ringwald modctx->tablepos = 0; 1083*a4cd9b30SMilanka Ringwald } 1084*a4cd9b30SMilanka Ringwald } 1085*a4cd9b30SMilanka Ringwald else 1086*a4cd9b30SMilanka Ringwald { 1087*a4cd9b30SMilanka Ringwald modctx->patterndelay--; 1088*a4cd9b30SMilanka Ringwald modctx->patternticks = 0; 1089*a4cd9b30SMilanka Ringwald modctx->patterntickse = 0; 1090*a4cd9b30SMilanka Ringwald } 1091*a4cd9b30SMilanka Ringwald 1092*a4cd9b30SMilanka Ringwald } 1093*a4cd9b30SMilanka Ringwald 1094*a4cd9b30SMilanka Ringwald if( modctx->patterntickse++ > (modctx->patternticksaim/modctx->song.speed) ) 1095*a4cd9b30SMilanka Ringwald { 1096*a4cd9b30SMilanka Ringwald nptr = modctx->patterndata[modctx->song.patterntable[modctx->tablepos]]; 1097*a4cd9b30SMilanka Ringwald nptr = nptr + modctx->patternpos; 1098*a4cd9b30SMilanka Ringwald cptr = modctx->channels; 1099*a4cd9b30SMilanka Ringwald 1100*a4cd9b30SMilanka Ringwald for(c=0;c<modctx->number_of_channels;c++) 1101*a4cd9b30SMilanka Ringwald { 1102*a4cd9b30SMilanka Ringwald workeffect(nptr+c, cptr+c); 1103*a4cd9b30SMilanka Ringwald } 1104*a4cd9b30SMilanka Ringwald 1105*a4cd9b30SMilanka Ringwald modctx->patterntickse = 0; 1106*a4cd9b30SMilanka Ringwald } 1107*a4cd9b30SMilanka Ringwald 1108*a4cd9b30SMilanka Ringwald //--------------------------------------- 1109*a4cd9b30SMilanka Ringwald 1110*a4cd9b30SMilanka Ringwald if( trkbuf && !state_remaining_steps ) 1111*a4cd9b30SMilanka Ringwald { 1112*a4cd9b30SMilanka Ringwald if( trkbuf->nb_of_state < trkbuf->nb_max_of_state ) 1113*a4cd9b30SMilanka Ringwald { 1114*a4cd9b30SMilanka Ringwald memclear(&trkbuf->track_state_buf[trkbuf->nb_of_state],0,sizeof(tracker_state)); 1115*a4cd9b30SMilanka Ringwald } 1116*a4cd9b30SMilanka Ringwald } 1117*a4cd9b30SMilanka Ringwald 1118*a4cd9b30SMilanka Ringwald l=0; 1119*a4cd9b30SMilanka Ringwald r=0; 1120*a4cd9b30SMilanka Ringwald 1121*a4cd9b30SMilanka Ringwald for(j =0, cptr = modctx->channels; j < modctx->number_of_channels ; j++, cptr++) 1122*a4cd9b30SMilanka Ringwald { 1123*a4cd9b30SMilanka Ringwald if( cptr->period != 0 ) 1124*a4cd9b30SMilanka Ringwald { 1125*a4cd9b30SMilanka Ringwald finalperiod = cptr->period - cptr->decalperiod - cptr->vibraperiod; 1126*a4cd9b30SMilanka Ringwald if( finalperiod ) 1127*a4cd9b30SMilanka Ringwald { 1128*a4cd9b30SMilanka Ringwald cptr->samppos += ( (modctx->sampleticksconst<<10) / finalperiod ); 1129*a4cd9b30SMilanka Ringwald } 1130*a4cd9b30SMilanka Ringwald 1131*a4cd9b30SMilanka Ringwald cptr->ticks++; 1132*a4cd9b30SMilanka Ringwald 1133*a4cd9b30SMilanka Ringwald if( cptr->replen<=2 ) 1134*a4cd9b30SMilanka Ringwald { 1135*a4cd9b30SMilanka Ringwald if( (cptr->samppos>>10) >= (cptr->length) ) 1136*a4cd9b30SMilanka Ringwald { 1137*a4cd9b30SMilanka Ringwald cptr->length = 0; 1138*a4cd9b30SMilanka Ringwald cptr->reppnt = 0; 1139*a4cd9b30SMilanka Ringwald 1140*a4cd9b30SMilanka Ringwald if( cptr->length ) 1141*a4cd9b30SMilanka Ringwald cptr->samppos = cptr->samppos % (((unsigned long)cptr->length)<<10); 1142*a4cd9b30SMilanka Ringwald else 1143*a4cd9b30SMilanka Ringwald cptr->samppos = 0; 1144*a4cd9b30SMilanka Ringwald } 1145*a4cd9b30SMilanka Ringwald } 1146*a4cd9b30SMilanka Ringwald else 1147*a4cd9b30SMilanka Ringwald { 1148*a4cd9b30SMilanka Ringwald if( (cptr->samppos>>10) >= (unsigned long)(cptr->replen+cptr->reppnt) ) 1149*a4cd9b30SMilanka Ringwald { 1150*a4cd9b30SMilanka Ringwald cptr->samppos = ((unsigned long)(cptr->reppnt)<<10) + (cptr->samppos % ((unsigned long)(cptr->replen+cptr->reppnt)<<10)); 1151*a4cd9b30SMilanka Ringwald } 1152*a4cd9b30SMilanka Ringwald } 1153*a4cd9b30SMilanka Ringwald 1154*a4cd9b30SMilanka Ringwald k = cptr->samppos >> 10; 1155*a4cd9b30SMilanka Ringwald 1156*a4cd9b30SMilanka Ringwald if( cptr->sampdata!=0 && ( ((j&3)==1) || ((j&3)==2) ) ) 1157*a4cd9b30SMilanka Ringwald { 1158*a4cd9b30SMilanka Ringwald r += ( cptr->sampdata[k] * cptr->volume ); 1159*a4cd9b30SMilanka Ringwald } 1160*a4cd9b30SMilanka Ringwald 1161*a4cd9b30SMilanka Ringwald if( cptr->sampdata!=0 && ( ((j&3)==0) || ((j&3)==3) ) ) 1162*a4cd9b30SMilanka Ringwald { 1163*a4cd9b30SMilanka Ringwald l += ( cptr->sampdata[k] * cptr->volume ); 1164*a4cd9b30SMilanka Ringwald } 1165*a4cd9b30SMilanka Ringwald 1166*a4cd9b30SMilanka Ringwald if( trkbuf && !state_remaining_steps ) 1167*a4cd9b30SMilanka Ringwald { 1168*a4cd9b30SMilanka Ringwald if( trkbuf->nb_of_state < trkbuf->nb_max_of_state ) 1169*a4cd9b30SMilanka Ringwald { 1170*a4cd9b30SMilanka Ringwald trkbuf->track_state_buf[trkbuf->nb_of_state].number_of_tracks = modctx->number_of_channels; 1171*a4cd9b30SMilanka Ringwald trkbuf->track_state_buf[trkbuf->nb_of_state].buf_index = i; 1172*a4cd9b30SMilanka Ringwald trkbuf->track_state_buf[trkbuf->nb_of_state].cur_pattern = modctx->song.patterntable[modctx->tablepos]; 1173*a4cd9b30SMilanka Ringwald trkbuf->track_state_buf[trkbuf->nb_of_state].cur_pattern_pos = modctx->patternpos / modctx->number_of_channels; 1174*a4cd9b30SMilanka Ringwald trkbuf->track_state_buf[trkbuf->nb_of_state].cur_pattern_table_pos = modctx->tablepos; 1175*a4cd9b30SMilanka Ringwald trkbuf->track_state_buf[trkbuf->nb_of_state].bpm = modctx->bpm; 1176*a4cd9b30SMilanka Ringwald trkbuf->track_state_buf[trkbuf->nb_of_state].speed = modctx->song.speed; 1177*a4cd9b30SMilanka Ringwald trkbuf->track_state_buf[trkbuf->nb_of_state].tracks[j].cur_effect = cptr->effect_code; 1178*a4cd9b30SMilanka Ringwald trkbuf->track_state_buf[trkbuf->nb_of_state].tracks[j].cur_parameffect = cptr->parameffect; 1179*a4cd9b30SMilanka Ringwald trkbuf->track_state_buf[trkbuf->nb_of_state].tracks[j].cur_period = finalperiod; 1180*a4cd9b30SMilanka Ringwald trkbuf->track_state_buf[trkbuf->nb_of_state].tracks[j].cur_volume = cptr->volume; 1181*a4cd9b30SMilanka Ringwald trkbuf->track_state_buf[trkbuf->nb_of_state].tracks[j].instrument_number = (unsigned char)cptr->sampnum; 1182*a4cd9b30SMilanka Ringwald } 1183*a4cd9b30SMilanka Ringwald } 1184*a4cd9b30SMilanka Ringwald } 1185*a4cd9b30SMilanka Ringwald } 1186*a4cd9b30SMilanka Ringwald 1187*a4cd9b30SMilanka Ringwald if( trkbuf && !state_remaining_steps ) 1188*a4cd9b30SMilanka Ringwald { 1189*a4cd9b30SMilanka Ringwald state_remaining_steps = trkbuf->sample_step; 1190*a4cd9b30SMilanka Ringwald 1191*a4cd9b30SMilanka Ringwald if(trkbuf->nb_of_state < trkbuf->nb_max_of_state) 1192*a4cd9b30SMilanka Ringwald trkbuf->nb_of_state++; 1193*a4cd9b30SMilanka Ringwald } 1194*a4cd9b30SMilanka Ringwald else 1195*a4cd9b30SMilanka Ringwald { 1196*a4cd9b30SMilanka Ringwald state_remaining_steps--; 1197*a4cd9b30SMilanka Ringwald } 1198*a4cd9b30SMilanka Ringwald 1199*a4cd9b30SMilanka Ringwald tl = (short)l; 1200*a4cd9b30SMilanka Ringwald tr = (short)r; 1201*a4cd9b30SMilanka Ringwald 1202*a4cd9b30SMilanka Ringwald if ( modctx->filter ) 1203*a4cd9b30SMilanka Ringwald { 1204*a4cd9b30SMilanka Ringwald // Filter 1205*a4cd9b30SMilanka Ringwald l = (l+ll)>>1; 1206*a4cd9b30SMilanka Ringwald r = (r+lr)>>1; 1207*a4cd9b30SMilanka Ringwald } 1208*a4cd9b30SMilanka Ringwald 1209*a4cd9b30SMilanka Ringwald if ( modctx->stereo_separation == 1 ) 1210*a4cd9b30SMilanka Ringwald { 1211*a4cd9b30SMilanka Ringwald // Left & Right Stereo panning 1212*a4cd9b30SMilanka Ringwald l = (l+(r>>1)); 1213*a4cd9b30SMilanka Ringwald r = (r+(l>>1)); 1214*a4cd9b30SMilanka Ringwald } 1215*a4cd9b30SMilanka Ringwald 1216*a4cd9b30SMilanka Ringwald // Level limitation 1217*a4cd9b30SMilanka Ringwald if( l > 32767 ) l = 32767; 1218*a4cd9b30SMilanka Ringwald if( l < -32768 ) l = -32768; 1219*a4cd9b30SMilanka Ringwald if( r > 32767 ) r = 32767; 1220*a4cd9b30SMilanka Ringwald if( r < -32768 ) r = -32768; 1221*a4cd9b30SMilanka Ringwald 1222*a4cd9b30SMilanka Ringwald // Store the final sample. 1223*a4cd9b30SMilanka Ringwald outbuffer[(i*2)] = l; 1224*a4cd9b30SMilanka Ringwald outbuffer[(i*2)+1] = r; 1225*a4cd9b30SMilanka Ringwald 1226*a4cd9b30SMilanka Ringwald ll = tl; 1227*a4cd9b30SMilanka Ringwald lr = tr; 1228*a4cd9b30SMilanka Ringwald 1229*a4cd9b30SMilanka Ringwald } 1230*a4cd9b30SMilanka Ringwald 1231*a4cd9b30SMilanka Ringwald modctx->last_l_sample = ll; 1232*a4cd9b30SMilanka Ringwald modctx->last_r_sample = lr; 1233*a4cd9b30SMilanka Ringwald 1234*a4cd9b30SMilanka Ringwald modctx->samplenb = modctx->samplenb+nbsample; 1235*a4cd9b30SMilanka Ringwald } 1236*a4cd9b30SMilanka Ringwald else 1237*a4cd9b30SMilanka Ringwald { 1238*a4cd9b30SMilanka Ringwald for (i = 0; i < nbsample; i++) 1239*a4cd9b30SMilanka Ringwald { 1240*a4cd9b30SMilanka Ringwald // Mod not loaded. Return blank buffer. 1241*a4cd9b30SMilanka Ringwald outbuffer[(i*2)] = 0; 1242*a4cd9b30SMilanka Ringwald outbuffer[(i*2)+1] = 0; 1243*a4cd9b30SMilanka Ringwald } 1244*a4cd9b30SMilanka Ringwald 1245*a4cd9b30SMilanka Ringwald if(trkbuf) 1246*a4cd9b30SMilanka Ringwald { 1247*a4cd9b30SMilanka Ringwald trkbuf->nb_of_state = 0; 1248*a4cd9b30SMilanka Ringwald trkbuf->cur_rd_index = 0; 1249*a4cd9b30SMilanka Ringwald trkbuf->name[0] = 0; 1250*a4cd9b30SMilanka Ringwald memclear(trkbuf->track_state_buf,0,sizeof(tracker_state) * trkbuf->nb_max_of_state); 1251*a4cd9b30SMilanka Ringwald memclear(trkbuf->instruments,0,sizeof(trkbuf->instruments)); 1252*a4cd9b30SMilanka Ringwald } 1253*a4cd9b30SMilanka Ringwald } 1254*a4cd9b30SMilanka Ringwald } 1255*a4cd9b30SMilanka Ringwald } 1256*a4cd9b30SMilanka Ringwald 1257*a4cd9b30SMilanka Ringwald void hxcmod_unload( modcontext * modctx ) 1258*a4cd9b30SMilanka Ringwald { 1259*a4cd9b30SMilanka Ringwald if(modctx) 1260*a4cd9b30SMilanka Ringwald { 1261*a4cd9b30SMilanka Ringwald memclear(&modctx->song,0,sizeof(modctx->song)); 1262*a4cd9b30SMilanka Ringwald memclear(&modctx->sampledata,0,sizeof(modctx->sampledata)); 1263*a4cd9b30SMilanka Ringwald memclear(&modctx->patterndata,0,sizeof(modctx->patterndata)); 1264*a4cd9b30SMilanka Ringwald modctx->tablepos = 0; 1265*a4cd9b30SMilanka Ringwald modctx->patternpos = 0; 1266*a4cd9b30SMilanka Ringwald modctx->patterndelay = 0; 1267*a4cd9b30SMilanka Ringwald modctx->jump_loop_effect = 0; 1268*a4cd9b30SMilanka Ringwald modctx->bpm = 0; 1269*a4cd9b30SMilanka Ringwald modctx->patternticks = 0; 1270*a4cd9b30SMilanka Ringwald modctx->patterntickse = 0; 1271*a4cd9b30SMilanka Ringwald modctx->patternticksaim = 0; 1272*a4cd9b30SMilanka Ringwald modctx->sampleticksconst = 0; 1273*a4cd9b30SMilanka Ringwald 1274*a4cd9b30SMilanka Ringwald modctx->samplenb = 0; 1275*a4cd9b30SMilanka Ringwald 1276*a4cd9b30SMilanka Ringwald memclear(modctx->channels,0,sizeof(modctx->channels)); 1277*a4cd9b30SMilanka Ringwald 1278*a4cd9b30SMilanka Ringwald modctx->number_of_channels = 0; 1279*a4cd9b30SMilanka Ringwald 1280*a4cd9b30SMilanka Ringwald modctx->mod_loaded = 0; 1281*a4cd9b30SMilanka Ringwald 1282*a4cd9b30SMilanka Ringwald modctx->last_r_sample = 0; 1283*a4cd9b30SMilanka Ringwald modctx->last_l_sample = 0; 1284*a4cd9b30SMilanka Ringwald } 1285*a4cd9b30SMilanka Ringwald } 1286