diff --git a/src/engine/cmdStream.cpp b/src/engine/cmdStream.cpp index 05f5326ed..210af399e 100644 --- a/src/engine/cmdStream.cpp +++ b/src/engine/cmdStream.cpp @@ -18,6 +18,7 @@ */ #include "cmdStream.h" +#include "dispatch.h" #include "engine.h" #include "../ta-log.h" @@ -58,7 +59,7 @@ bool DivCSPlayer::tick() { if (next<0xb3) { // note e->dispatchCmd(DivCommand(DIV_CMD_NOTE_ON,i,(int)next-60)); - logV("%d: note on (%d)",i,(int)next-60); + chan[i].note=(int)next-60; chan[i].vibratoPos=0; } else if (next>=0xd0 && next<=0xdf) { command=fastCmds[next&15]; @@ -156,6 +157,7 @@ bool DivCSPlayer::tick() { case DIV_CMD_HINT_VIBRATO_RANGE: case DIV_CMD_HINT_VIBRATO_SHAPE: case DIV_CMD_HINT_VOLUME: + case DIV_CMD_HINT_ARP_TIME: arg0=(unsigned char)stream.readC(); break; case DIV_CMD_HINT_PITCH: @@ -299,6 +301,12 @@ bool DivCSPlayer::tick() { chan[i].note=arg0; e->dispatchCmd(DivCommand(DIV_CMD_LEGATO,i,chan[i].note)); break; + case DIV_CMD_HINT_ARPEGGIO: + chan[i].arp=(((unsigned char)arg0)<<4)|(arg1&15); + break; + case DIV_CMD_HINT_ARP_TIME: + arpSpeed=arg0; + break; default: // dispatch it e->dispatchCmd(DivCommand((DivDispatchCmds)command,i,arg0,arg1)); break; @@ -331,6 +339,25 @@ bool DivCSPlayer::tick() { if (chan[i].portaSpeed) { e->dispatchCmd(DivCommand(DIV_CMD_NOTE_PORTA,i,chan[i].portaSpeed*(e->song.linearPitch==2?e->song.pitchSlideSpeed:1),chan[i].portaTarget)); } + if (chan[i].arp && !chan[i].portaSpeed) { + if (chan[i].arpTicks==0) { + switch (chan[i].arpStage) { + case 0: + e->dispatchCmd(DivCommand(DIV_CMD_LEGATO,i,chan[i].note)); + break; + case 1: + e->dispatchCmd(DivCommand(DIV_CMD_LEGATO,i,chan[i].note+(chan[i].arp>>4))); + break; + case 2: + e->dispatchCmd(DivCommand(DIV_CMD_LEGATO,i,chan[i].note+(chan[i].arp&15))); + break; + } + chan[i].arpStage++; + if (chan[i].arpStage>=3) chan[i].arpStage=0; + chan[i].arpTicks=arpSpeed; + } + chan[i].arpTicks--; + } } return ticked; @@ -370,6 +397,8 @@ bool DivCSPlayer::init() { vibTable[i]=127*sin(((double)i/64.0)*(2*M_PI)); } + arpSpeed=1; + return true; } diff --git a/src/engine/cmdStream.h b/src/engine/cmdStream.h index ac25077b6..0c660b7af 100644 --- a/src/engine/cmdStream.h +++ b/src/engine/cmdStream.h @@ -73,6 +73,7 @@ class DivCSPlayer { DivCSChannelState chan[DIV_MAX_CHANS]; unsigned char fastDelays[16]; unsigned char fastCmds[16]; + unsigned char arpSpeed; short vibTable[64]; public: diff --git a/src/engine/dispatch.h b/src/engine/dispatch.h index 1d5932b69..0c9d2ca74 100644 --- a/src/engine/dispatch.h +++ b/src/engine/dispatch.h @@ -229,6 +229,8 @@ enum DivDispatchCmds { DIV_CMD_ES5506_ENVELOPE_K2RAMP, // (ramp, slowdown) DIV_CMD_ES5506_PAUSE, // (value) + DIV_CMD_HINT_ARP_TIME, // (value) + DIV_ALWAYS_SET_VOLUME, // () -> alwaysSetVol DIV_CMD_MAX diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index a3669a184..008054114 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -418,6 +418,7 @@ void writePackedCommandValues(SafeWriter* w, const DivCommand& c) { case DIV_CMD_AMIGA_PM: case DIV_CMD_MACRO_OFF: case DIV_CMD_MACRO_ON: + case DIV_CMD_HINT_ARP_TIME: w->writeC(1); // length w->writeC(c.value); break; diff --git a/src/engine/playback.cpp b/src/engine/playback.cpp index e9352bf9c..6c3db8053 100644 --- a/src/engine/playback.cpp +++ b/src/engine/playback.cpp @@ -229,6 +229,8 @@ const char* cmdName[]={ "ES5506_ENVELOPE_K2RAMP", "ES5506_PAUSE", + "HINT_ARP_TIME", + "ALWAYS_SET_VOLUME" }; @@ -765,6 +767,7 @@ void DivEngine::processRow(int i, bool afterDelay) { case 0xe0: // arp speed if (effectVal>0) { curSubSong->arpLen=effectVal; + dispatchCmd(DivCommand(DIV_CMD_HINT_ARP_TIME,i,curSubSong->arpLen)); } break; case 0xe1: // portamento up