/* Extended Module Player * Copyright (C) 1996-1999 Claudio Matsuoka and Hipolito Carraro Jr * * This file is part of the Extended Module Player and is distributed * under the terms of the GNU General Public License. See doc/COPYING * for more information. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "xmpi.h" #include "player.h" #include "driver.h" /* Commands in the volume and waveform sequence table: * * Cmd Vol Wave Action * * 0xff END End sequence * 0xfe JMP Jump * 0xfd - ARE End arpeggio definition * 0xfc - ARP Begin arpeggio definition * 0xfb HLT Halt * 0xfa JWS JVS Jump waveform/volume sequence * 0xf9 - - * 0xf8 - - * 0xf7 - VWF Set vibrato waveform * 0xf6 EST RES ?/reset pitch * 0xf5 EN2 VBS Looping envelope/set vibrato speed * 0xf4 EN1 VBD One shot envelope/set vibrato depth * 0xf3 CHU Change volume/pitch up speed * 0xf2 CHD Change volume/pitch down speed * 0xf1 WAI Wait * 0xf0 SPD Set speed */ extern uint8 **med_vol_table; extern uint8 **med_wav_table; #define VT med_vol_table[xc->ins][xc->med_vp++] #define WT med_wav_table[xc->ins][xc->med_wp++] #define VT_SKIP xc->med_vp++ #define WT_SKIP xc->med_wp++ void xmp_med_synth (int chn, struct xmp_channel *xc, int rst) { int b, jws = 0, jvs = 0, loop = 0, jump = 0; if (med_vol_table == NULL || med_wav_table == NULL) return; if (med_vol_table[xc->ins] == NULL || med_wav_table[xc->ins] == NULL) return; if (rst) { xc->med_period = xc->period; xc->med_vp = xc->med_vc = xc->med_vw = 0; xc->med_wp = xc->med_wc = xc->med_ww = 0; xc->med_vs = xxih[xc->ins].vts; xc->med_ws = xxih[xc->ins].wts; } if (xc->med_vs > 0 && xc->med_vc-- == 0) { xc->med_vc = xc->med_vs - 1; if (xc->med_vw > 0) { xc->med_vw--; goto skip_vol; } jump = loop = jws = 0; switch (b = VT) { while (jump--) { case 0xff: /* END */ case 0xfb: /* HLT */ xc->med_vp--; break; case 0xfe: /* JMP */ if (loop) /* avoid infinite loop */ break; xc->med_vp = VT; loop = jump = 1; break; case 0xfa: /* JWS */ jws = VT; break; case 0xf5: /* EN2 */ case 0xf4: /* EN1 */ VT_SKIP; /* Not implemented */ break; case 0xf3: /* CHU */ xc->med_vv = VT; break; case 0xf2: /* CHD */ xc->med_vv = -VT; break; case 0xf1: /* WAI */ xc->med_vw = VT; break; case 0xf0: /* SPD */ xc->med_vs = VT; break; default: if (b >= 0x00 && b <= 0x40) xc->volume = b; } } skip_vol: if (xc->med_ww > 0) { xc->med_ww--; goto skip_wav; } jump = loop = jvs = 0; switch (b = WT) { while (jump--) { case 0xff: /* END */ case 0xfb: /* HLT */ xc->med_wp--; break; case 0xfe: /* JMP */ if (loop) /* avoid infinite loop */ break; xc->med_wp = WT; loop = jump = 1; break; case 0xfc: /* ARP */ while (WT != 0xfd); break; case 0xfa: /* JVS */ jws = WT; break; case 0xf7: /* VWF */ xc->y_type = WT; break; case 0xf6: /* RES */ xc->period = xc->med_period; break; case 0xf5: /* VBS */ xc->y_rate = WT; break; case 0xf4: /* VBD */ xc->y_depth = WT; break; case 0xf3: /* CHU */ xc->med_wv = -WT; break; case 0xf2: /* CHD */ xc->med_wv = WT; break; case 0xf1: /* WAI */ xc->med_ww = WT; break; case 0xf0: /* SPD */ xc->med_ws = WT; break; default: if (b < xxih[xc->ins].nsm && xxi[xc->ins][b].sid != xc->smp) xmp_drv_setsmp (chn, xc->smp = xxi[xc->ins][b].sid); } } skip_wav: xc->volume += xc->med_vv; if (xc->volume < 0) xc->volume = 0; if (xc->volume > 64) xc->volume = 64; /* xc->period += xc->med_wv; */ } if (jws) { xc->med_wp = jws; jws = 0; } if (jvs) { xc->med_vp = jvs; jvs = 0; } }