more command stream playback work
This commit is contained in:
parent
84e13cc91e
commit
da7d67fa85
|
@ -69,10 +69,13 @@ hex | description
|
||||||
.. | ...
|
.. | ...
|
||||||
ef | preset delay 15
|
ef | preset delay 15
|
||||||
----|------------------------------------
|
----|------------------------------------
|
||||||
|
f4 | call symbol (16-bit index follows; only used internally)
|
||||||
|
f5 | jump to sub-block (address follows)
|
||||||
|
f6 | go to sub-block (32-bit offset follows)
|
||||||
f7 | full command (command and data follows)
|
f7 | full command (command and data follows)
|
||||||
f8 | go to sub-block (offset follows)
|
f8 | go to sub-block (16-bit offset follows)
|
||||||
f9 | return from sub-block
|
f9 | return from sub-block
|
||||||
fa | jump (offset follows)
|
fa | jump (address follows)
|
||||||
fb | set tick rate (4 bytes)
|
fb | set tick rate (4 bytes)
|
||||||
fc | wait (16-bit)
|
fc | wait (16-bit)
|
||||||
fd | wait (8-bit)
|
fd | wait (8-bit)
|
||||||
|
|
|
@ -21,6 +21,18 @@
|
||||||
#include "engine.h"
|
#include "engine.h"
|
||||||
#include "../ta-log.h"
|
#include "../ta-log.h"
|
||||||
|
|
||||||
|
bool DivCSChannelState::doCall(unsigned int addr) {
|
||||||
|
if (callStackPos>=8) {
|
||||||
|
readPos=0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
callStack[callStackPos++]=readPos;
|
||||||
|
readPos=addr;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void DivCSPlayer::cleanup() {
|
void DivCSPlayer::cleanup() {
|
||||||
delete b;
|
delete b;
|
||||||
}
|
}
|
||||||
|
@ -29,18 +41,25 @@ bool DivCSPlayer::tick() {
|
||||||
bool ticked=false;
|
bool ticked=false;
|
||||||
for (int i=0; i<e->getTotalChannelCount(); i++) {
|
for (int i=0; i<e->getTotalChannelCount(); i++) {
|
||||||
bool sendVolume=false;
|
bool sendVolume=false;
|
||||||
|
bool sendPitch=false;
|
||||||
if (chan[i].readPos==0) continue;
|
if (chan[i].readPos==0) continue;
|
||||||
|
|
||||||
ticked=true;
|
ticked=true;
|
||||||
|
|
||||||
chan[i].waitTicks--;
|
chan[i].waitTicks--;
|
||||||
while (chan[i].waitTicks<=0) {
|
while (chan[i].waitTicks<=0) {
|
||||||
stream.seek(chan[i].readPos,SEEK_SET);
|
if (!stream.seek(chan[i].readPos,SEEK_SET)) {
|
||||||
|
logE("%d: access violation! $%x",i,chan[i].readPos);
|
||||||
|
chan[i].readPos=0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
unsigned char next=stream.readC();
|
unsigned char next=stream.readC();
|
||||||
unsigned char command=0;
|
unsigned char command=0;
|
||||||
|
|
||||||
if (next<0xb3) { // note
|
if (next<0xb3) { // note
|
||||||
e->dispatchCmd(DivCommand(DIV_CMD_NOTE_ON,i,next-60));
|
e->dispatchCmd(DivCommand(DIV_CMD_NOTE_ON,i,(int)next-60));
|
||||||
|
logV("%d: note on (%d)",i,(int)next-60);
|
||||||
|
chan[i].vibratoPos=0;
|
||||||
} else if (next>=0xd0 && next<=0xdf) {
|
} else if (next>=0xd0 && next<=0xdf) {
|
||||||
command=fastCmds[next&15];
|
command=fastCmds[next&15];
|
||||||
} else if (next>=0xe0 && next<=0xef) { // preset delay
|
} else if (next>=0xe0 && next<=0xef) { // preset delay
|
||||||
|
@ -48,6 +67,7 @@ bool DivCSPlayer::tick() {
|
||||||
} else switch (next) {
|
} else switch (next) {
|
||||||
case 0xb4: // note on null
|
case 0xb4: // note on null
|
||||||
e->dispatchCmd(DivCommand(DIV_CMD_NOTE_ON,i,DIV_NOTE_NULL));
|
e->dispatchCmd(DivCommand(DIV_CMD_NOTE_ON,i,DIV_NOTE_NULL));
|
||||||
|
chan[i].vibratoPos=0;
|
||||||
break;
|
break;
|
||||||
case 0xb5: // note off
|
case 0xb5: // note off
|
||||||
e->dispatchCmd(DivCommand(DIV_CMD_NOTE_OFF,i));
|
e->dispatchCmd(DivCommand(DIV_CMD_NOTE_OFF,i));
|
||||||
|
@ -66,17 +86,46 @@ bool DivCSPlayer::tick() {
|
||||||
case 0xf7:
|
case 0xf7:
|
||||||
command=stream.readC();
|
command=stream.readC();
|
||||||
break;
|
break;
|
||||||
case 0xf8:
|
case 0xf8: {
|
||||||
logE("TODO: CALL");
|
unsigned int callAddr=chan[i].readPos+2+stream.readS();
|
||||||
|
if (!chan[i].doCall(callAddr)) {
|
||||||
|
logE("%d: (callb16) stack error!",i);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
case 0xf6: {
|
||||||
|
unsigned int callAddr=chan[i].readPos+4+stream.readI();
|
||||||
|
if (!chan[i].doCall(callAddr)) {
|
||||||
|
logE("%d: (callb32) stack error!",i);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0xf5: {
|
||||||
|
unsigned int callAddr=stream.readI();
|
||||||
|
if (!chan[i].doCall(callAddr)) {
|
||||||
|
logE("%d: (call) stack error!",i);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0xf4: {
|
||||||
|
logE("%d: (callsym) not supported here!",i);
|
||||||
|
chan[i].readPos=0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case 0xf9:
|
case 0xf9:
|
||||||
logE("TODO: RET");
|
if (!chan[i].callStackPos) {
|
||||||
|
logE("%d: (ret) stack error!",i);
|
||||||
|
chan[i].readPos=0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
chan[i].readPos=chan[i].callStack[--chan[i].callStackPos];
|
||||||
break;
|
break;
|
||||||
case 0xfa:
|
case 0xfa:
|
||||||
logE("TODO: JMP");
|
chan[i].readPos=stream.readI();
|
||||||
break;
|
break;
|
||||||
case 0xfb:
|
case 0xfb:
|
||||||
logE("TODO: RATE");
|
logE("TODO: RATE");
|
||||||
|
stream.readI();
|
||||||
break;
|
break;
|
||||||
case 0xfc:
|
case 0xfc:
|
||||||
chan[i].waitTicks=(unsigned short)stream.readS();
|
chan[i].waitTicks=(unsigned short)stream.readS();
|
||||||
|
@ -88,6 +137,11 @@ bool DivCSPlayer::tick() {
|
||||||
chan[i].waitTicks=1;
|
chan[i].waitTicks=1;
|
||||||
break;
|
break;
|
||||||
case 0xff:
|
case 0xff:
|
||||||
|
chan[i].readPos=0;
|
||||||
|
logI("%d: stop",i);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
logE("%d: illegal instruction $%.2x! $%.x",i,next,chan[i].readPos);
|
||||||
chan[i].readPos=0;
|
chan[i].readPos=0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -101,15 +155,17 @@ bool DivCSPlayer::tick() {
|
||||||
case DIV_CMD_INSTRUMENT:
|
case DIV_CMD_INSTRUMENT:
|
||||||
case DIV_CMD_HINT_VIBRATO_RANGE:
|
case DIV_CMD_HINT_VIBRATO_RANGE:
|
||||||
case DIV_CMD_HINT_VIBRATO_SHAPE:
|
case DIV_CMD_HINT_VIBRATO_SHAPE:
|
||||||
case DIV_CMD_HINT_PITCH:
|
|
||||||
case DIV_CMD_HINT_VOLUME:
|
case DIV_CMD_HINT_VOLUME:
|
||||||
arg0=(unsigned char)stream.readC();
|
arg0=(unsigned char)stream.readC();
|
||||||
break;
|
break;
|
||||||
|
case DIV_CMD_HINT_PITCH:
|
||||||
|
arg0=(signed char)stream.readC();
|
||||||
|
break;
|
||||||
case DIV_CMD_PANNING:
|
case DIV_CMD_PANNING:
|
||||||
case DIV_CMD_HINT_VIBRATO:
|
case DIV_CMD_HINT_VIBRATO:
|
||||||
case DIV_CMD_HINT_ARPEGGIO:
|
case DIV_CMD_HINT_ARPEGGIO:
|
||||||
case DIV_CMD_HINT_PORTA:
|
case DIV_CMD_HINT_PORTA:
|
||||||
arg0=(unsigned char)stream.readC();
|
arg0=(signed char)stream.readC();
|
||||||
arg1=(unsigned char)stream.readC();
|
arg1=(unsigned char)stream.readC();
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_PRE_PORTA:
|
case DIV_CMD_PRE_PORTA:
|
||||||
|
@ -120,6 +176,14 @@ bool DivCSPlayer::tick() {
|
||||||
case DIV_CMD_HINT_VOL_SLIDE:
|
case DIV_CMD_HINT_VOL_SLIDE:
|
||||||
arg0=(short)stream.readS();
|
arg0=(short)stream.readS();
|
||||||
break;
|
break;
|
||||||
|
case DIV_CMD_HINT_LEGATO:
|
||||||
|
arg0=(unsigned char)stream.readC();
|
||||||
|
if (arg0==0xff) {
|
||||||
|
arg0=DIV_NOTE_NULL;
|
||||||
|
} else {
|
||||||
|
arg0-=60;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case DIV_CMD_SAMPLE_MODE:
|
case DIV_CMD_SAMPLE_MODE:
|
||||||
case DIV_CMD_SAMPLE_FREQ:
|
case DIV_CMD_SAMPLE_FREQ:
|
||||||
case DIV_CMD_SAMPLE_BANK:
|
case DIV_CMD_SAMPLE_BANK:
|
||||||
|
@ -218,6 +282,23 @@ bool DivCSPlayer::tick() {
|
||||||
case DIV_CMD_HINT_VOL_SLIDE:
|
case DIV_CMD_HINT_VOL_SLIDE:
|
||||||
chan[i].volSpeed=arg0;
|
chan[i].volSpeed=arg0;
|
||||||
break;
|
break;
|
||||||
|
case DIV_CMD_HINT_PITCH:
|
||||||
|
chan[i].pitch=arg0;
|
||||||
|
sendPitch=true;
|
||||||
|
break;
|
||||||
|
case DIV_CMD_HINT_VIBRATO:
|
||||||
|
chan[i].vibratoDepth=arg0;
|
||||||
|
chan[i].vibratoRate=arg1;
|
||||||
|
sendPitch=true;
|
||||||
|
break;
|
||||||
|
case DIV_CMD_HINT_PORTA:
|
||||||
|
chan[i].portaTarget=arg0;
|
||||||
|
chan[i].portaSpeed=arg1;
|
||||||
|
break;
|
||||||
|
case DIV_CMD_HINT_LEGATO:
|
||||||
|
chan[i].note=arg0;
|
||||||
|
e->dispatchCmd(DivCommand(DIV_CMD_LEGATO,i,chan[i].note));
|
||||||
|
break;
|
||||||
default: // dispatch it
|
default: // dispatch it
|
||||||
e->dispatchCmd(DivCommand((DivDispatchCmds)command,i,arg0,arg1));
|
e->dispatchCmd(DivCommand((DivDispatchCmds)command,i,arg0,arg1));
|
||||||
break;
|
break;
|
||||||
|
@ -238,6 +319,18 @@ bool DivCSPlayer::tick() {
|
||||||
|
|
||||||
e->dispatchCmd(DivCommand(DIV_CMD_VOLUME,i,chan[i].volume>>8));
|
e->dispatchCmd(DivCommand(DIV_CMD_VOLUME,i,chan[i].volume>>8));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sendPitch || chan[i].vibratoDepth!=0) {
|
||||||
|
if (chan[i].vibratoDepth>0) {
|
||||||
|
chan[i].vibratoPos+=chan[i].vibratoRate;
|
||||||
|
if (chan[i].vibratoPos>=64) chan[i].vibratoPos-=64;
|
||||||
|
}
|
||||||
|
e->dispatchCmd(DivCommand(DIV_CMD_PITCH,i,chan[i].pitch+(vibTable[chan[i].vibratoPos&63]*chan[i].vibratoDepth)/15));
|
||||||
|
}
|
||||||
|
|
||||||
|
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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ticked;
|
return ticked;
|
||||||
|
@ -273,6 +366,10 @@ bool DivCSPlayer::init() {
|
||||||
chan[i].volume=chan[i].volMax;
|
chan[i].volume=chan[i].volMax;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int i=0; i<64; i++) {
|
||||||
|
vibTable[i]=127*sin(((double)i/64.0)*(2*M_PI));
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,14 +29,41 @@ struct DivCSChannelState {
|
||||||
unsigned int readPos;
|
unsigned int readPos;
|
||||||
int waitTicks;
|
int waitTicks;
|
||||||
|
|
||||||
|
int note, pitch;
|
||||||
int volume, volMax, volSpeed;
|
int volume, volMax, volSpeed;
|
||||||
|
int vibratoDepth, vibratoRate, vibratoPos;
|
||||||
|
int portaTarget, portaSpeed;
|
||||||
|
unsigned char arp, arpStage, arpTicks;
|
||||||
|
|
||||||
|
unsigned int callStack[8];
|
||||||
|
unsigned char callStackPos;
|
||||||
|
|
||||||
|
struct TraceEntry {
|
||||||
|
unsigned int addr;
|
||||||
|
unsigned char length;
|
||||||
|
unsigned char data[11];
|
||||||
|
} trace[32];
|
||||||
|
unsigned char tracePos;
|
||||||
|
|
||||||
|
bool doCall(unsigned int addr);
|
||||||
|
|
||||||
DivCSChannelState():
|
DivCSChannelState():
|
||||||
readPos(0),
|
readPos(0),
|
||||||
waitTicks(0),
|
waitTicks(0),
|
||||||
|
note(-1),
|
||||||
|
pitch(0),
|
||||||
volume(0x7f00),
|
volume(0x7f00),
|
||||||
volMax(0),
|
volMax(0),
|
||||||
volSpeed(0) {}
|
volSpeed(0),
|
||||||
|
vibratoDepth(0),
|
||||||
|
vibratoRate(0),
|
||||||
|
vibratoPos(0),
|
||||||
|
portaTarget(0),
|
||||||
|
portaSpeed(0),
|
||||||
|
arp(0),
|
||||||
|
arpStage(0),
|
||||||
|
arpTicks(0),
|
||||||
|
callStackPos(0) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class DivCSPlayer {
|
class DivCSPlayer {
|
||||||
|
@ -46,6 +73,8 @@ class DivCSPlayer {
|
||||||
DivCSChannelState chan[DIV_MAX_CHANS];
|
DivCSChannelState chan[DIV_MAX_CHANS];
|
||||||
unsigned char fastDelays[16];
|
unsigned char fastDelays[16];
|
||||||
unsigned char fastCmds[16];
|
unsigned char fastCmds[16];
|
||||||
|
|
||||||
|
short vibTable[64];
|
||||||
public:
|
public:
|
||||||
void cleanup();
|
void cleanup();
|
||||||
bool tick();
|
bool tick();
|
||||||
|
|
|
@ -510,13 +510,13 @@ void DivEngine::processRow(int i, bool afterDelay) {
|
||||||
if (chan[i].stopOnOff) {
|
if (chan[i].stopOnOff) {
|
||||||
chan[i].portaNote=-1;
|
chan[i].portaNote=-1;
|
||||||
chan[i].portaSpeed=-1;
|
chan[i].portaSpeed=-1;
|
||||||
dispatchCmd(DivCommand(DIV_CMD_HINT_PORTA,i,chan[i].portaNote,chan[i].portaSpeed));
|
dispatchCmd(DivCommand(DIV_CMD_HINT_PORTA,i,CLAMP(chan[i].portaNote,-128,127),MAX(chan[i].portaSpeed,0)));
|
||||||
chan[i].stopOnOff=false;
|
chan[i].stopOnOff=false;
|
||||||
}
|
}
|
||||||
if (disCont[dispatchOfChan[i]].dispatch->keyOffAffectsPorta(dispatchChanOfChan[i])) {
|
if (disCont[dispatchOfChan[i]].dispatch->keyOffAffectsPorta(dispatchChanOfChan[i])) {
|
||||||
chan[i].portaNote=-1;
|
chan[i].portaNote=-1;
|
||||||
chan[i].portaSpeed=-1;
|
chan[i].portaSpeed=-1;
|
||||||
dispatchCmd(DivCommand(DIV_CMD_HINT_PORTA,i,chan[i].portaNote,chan[i].portaSpeed));
|
dispatchCmd(DivCommand(DIV_CMD_HINT_PORTA,i,CLAMP(chan[i].portaNote,-128,127),MAX(chan[i].portaSpeed,0)));
|
||||||
/*if (i==2 && sysOfChan[i]==DIV_SYSTEM_SMS) {
|
/*if (i==2 && sysOfChan[i]==DIV_SYSTEM_SMS) {
|
||||||
chan[i+1].portaNote=-1;
|
chan[i+1].portaNote=-1;
|
||||||
chan[i+1].portaSpeed=-1;
|
chan[i+1].portaSpeed=-1;
|
||||||
|
@ -533,13 +533,13 @@ void DivEngine::processRow(int i, bool afterDelay) {
|
||||||
if (chan[i].stopOnOff) {
|
if (chan[i].stopOnOff) {
|
||||||
chan[i].portaNote=-1;
|
chan[i].portaNote=-1;
|
||||||
chan[i].portaSpeed=-1;
|
chan[i].portaSpeed=-1;
|
||||||
dispatchCmd(DivCommand(DIV_CMD_HINT_PORTA,i,chan[i].portaNote,chan[i].portaSpeed));
|
dispatchCmd(DivCommand(DIV_CMD_HINT_PORTA,i,CLAMP(chan[i].portaNote,-128,127),MAX(chan[i].portaSpeed,0)));
|
||||||
chan[i].stopOnOff=false;
|
chan[i].stopOnOff=false;
|
||||||
}
|
}
|
||||||
if (disCont[dispatchOfChan[i]].dispatch->keyOffAffectsPorta(dispatchChanOfChan[i])) {
|
if (disCont[dispatchOfChan[i]].dispatch->keyOffAffectsPorta(dispatchChanOfChan[i])) {
|
||||||
chan[i].portaNote=-1;
|
chan[i].portaNote=-1;
|
||||||
chan[i].portaSpeed=-1;
|
chan[i].portaSpeed=-1;
|
||||||
dispatchCmd(DivCommand(DIV_CMD_HINT_PORTA,i,chan[i].portaNote,chan[i].portaSpeed));
|
dispatchCmd(DivCommand(DIV_CMD_HINT_PORTA,i,CLAMP(chan[i].portaNote,-128,127),MAX(chan[i].portaSpeed,0)));
|
||||||
/*if (i==2 && sysOfChan[i]==DIV_SYSTEM_SMS) {
|
/*if (i==2 && sysOfChan[i]==DIV_SYSTEM_SMS) {
|
||||||
chan[i+1].portaNote=-1;
|
chan[i+1].portaNote=-1;
|
||||||
chan[i+1].portaSpeed=-1;
|
chan[i+1].portaSpeed=-1;
|
||||||
|
@ -632,13 +632,13 @@ void DivEngine::processRow(int i, bool afterDelay) {
|
||||||
if (effectVal==0) {
|
if (effectVal==0) {
|
||||||
chan[i].portaNote=-1;
|
chan[i].portaNote=-1;
|
||||||
chan[i].portaSpeed=-1;
|
chan[i].portaSpeed=-1;
|
||||||
dispatchCmd(DivCommand(DIV_CMD_HINT_PORTA,i,chan[i].portaNote,chan[i].portaSpeed));
|
dispatchCmd(DivCommand(DIV_CMD_HINT_PORTA,i,CLAMP(chan[i].portaNote,-128,127),MAX(chan[i].portaSpeed,0)));
|
||||||
chan[i].inPorta=false;
|
chan[i].inPorta=false;
|
||||||
if (!song.arpNonPorta) dispatchCmd(DivCommand(DIV_CMD_PRE_PORTA,i,false,0));
|
if (!song.arpNonPorta) dispatchCmd(DivCommand(DIV_CMD_PRE_PORTA,i,false,0));
|
||||||
} else {
|
} else {
|
||||||
chan[i].portaNote=song.limitSlides?0x60:255;
|
chan[i].portaNote=song.limitSlides?0x60:255;
|
||||||
chan[i].portaSpeed=effectVal;
|
chan[i].portaSpeed=effectVal;
|
||||||
dispatchCmd(DivCommand(DIV_CMD_HINT_PORTA,i,chan[i].portaNote,chan[i].portaSpeed));
|
dispatchCmd(DivCommand(DIV_CMD_HINT_PORTA,i,CLAMP(chan[i].portaNote,-128,127),MAX(chan[i].portaSpeed,0)));
|
||||||
chan[i].portaStop=true;
|
chan[i].portaStop=true;
|
||||||
chan[i].nowYouCanStop=false;
|
chan[i].nowYouCanStop=false;
|
||||||
chan[i].stopOnOff=false;
|
chan[i].stopOnOff=false;
|
||||||
|
@ -654,13 +654,13 @@ void DivEngine::processRow(int i, bool afterDelay) {
|
||||||
if (effectVal==0) {
|
if (effectVal==0) {
|
||||||
chan[i].portaNote=-1;
|
chan[i].portaNote=-1;
|
||||||
chan[i].portaSpeed=-1;
|
chan[i].portaSpeed=-1;
|
||||||
dispatchCmd(DivCommand(DIV_CMD_HINT_PORTA,i,chan[i].portaNote,chan[i].portaSpeed));
|
dispatchCmd(DivCommand(DIV_CMD_HINT_PORTA,i,CLAMP(chan[i].portaNote,-128,127),MAX(chan[i].portaSpeed,0)));
|
||||||
chan[i].inPorta=false;
|
chan[i].inPorta=false;
|
||||||
if (!song.arpNonPorta) dispatchCmd(DivCommand(DIV_CMD_PRE_PORTA,i,false,0));
|
if (!song.arpNonPorta) dispatchCmd(DivCommand(DIV_CMD_PRE_PORTA,i,false,0));
|
||||||
} else {
|
} else {
|
||||||
chan[i].portaNote=song.limitSlides?disCont[dispatchOfChan[i]].dispatch->getPortaFloor(dispatchChanOfChan[i]):-60;
|
chan[i].portaNote=song.limitSlides?disCont[dispatchOfChan[i]].dispatch->getPortaFloor(dispatchChanOfChan[i]):-60;
|
||||||
chan[i].portaSpeed=effectVal;
|
chan[i].portaSpeed=effectVal;
|
||||||
dispatchCmd(DivCommand(DIV_CMD_HINT_PORTA,i,chan[i].portaNote,chan[i].portaSpeed));
|
dispatchCmd(DivCommand(DIV_CMD_HINT_PORTA,i,CLAMP(chan[i].portaNote,-128,127),MAX(chan[i].portaSpeed,0)));
|
||||||
chan[i].portaStop=true;
|
chan[i].portaStop=true;
|
||||||
chan[i].nowYouCanStop=false;
|
chan[i].nowYouCanStop=false;
|
||||||
chan[i].stopOnOff=false;
|
chan[i].stopOnOff=false;
|
||||||
|
@ -674,7 +674,7 @@ void DivEngine::processRow(int i, bool afterDelay) {
|
||||||
if (effectVal==0) {
|
if (effectVal==0) {
|
||||||
chan[i].portaNote=-1;
|
chan[i].portaNote=-1;
|
||||||
chan[i].portaSpeed=-1;
|
chan[i].portaSpeed=-1;
|
||||||
dispatchCmd(DivCommand(DIV_CMD_HINT_PORTA,i,chan[i].portaNote,chan[i].portaSpeed));
|
dispatchCmd(DivCommand(DIV_CMD_HINT_PORTA,i,CLAMP(chan[i].portaNote,-128,127),MAX(chan[i].portaSpeed,0)));
|
||||||
chan[i].inPorta=false;
|
chan[i].inPorta=false;
|
||||||
dispatchCmd(DivCommand(DIV_CMD_PRE_PORTA,i,false,0));
|
dispatchCmd(DivCommand(DIV_CMD_PRE_PORTA,i,false,0));
|
||||||
} else {
|
} else {
|
||||||
|
@ -688,7 +688,7 @@ void DivEngine::processRow(int i, bool afterDelay) {
|
||||||
chan[i].inPorta=true;
|
chan[i].inPorta=true;
|
||||||
chan[i].wasShorthandPorta=false;
|
chan[i].wasShorthandPorta=false;
|
||||||
}
|
}
|
||||||
dispatchCmd(DivCommand(DIV_CMD_HINT_PORTA,i,chan[i].portaNote,chan[i].portaSpeed));
|
dispatchCmd(DivCommand(DIV_CMD_HINT_PORTA,i,CLAMP(chan[i].portaNote,-128,127),MAX(chan[i].portaSpeed,0)));
|
||||||
chan[i].portaStop=true;
|
chan[i].portaStop=true;
|
||||||
if (chan[i].keyOn) chan[i].doNote=false;
|
if (chan[i].keyOn) chan[i].doNote=false;
|
||||||
chan[i].stopOnOff=song.stopPortaOnNoteOff; // what?!
|
chan[i].stopOnOff=song.stopPortaOnNoteOff; // what?!
|
||||||
|
@ -770,7 +770,7 @@ void DivEngine::processRow(int i, bool afterDelay) {
|
||||||
case 0xe1: // portamento up
|
case 0xe1: // portamento up
|
||||||
chan[i].portaNote=chan[i].note+(effectVal&15);
|
chan[i].portaNote=chan[i].note+(effectVal&15);
|
||||||
chan[i].portaSpeed=(effectVal>>4)*4;
|
chan[i].portaSpeed=(effectVal>>4)*4;
|
||||||
dispatchCmd(DivCommand(DIV_CMD_HINT_PORTA,i,chan[i].portaNote,chan[i].portaSpeed));
|
dispatchCmd(DivCommand(DIV_CMD_HINT_PORTA,i,CLAMP(chan[i].portaNote,-128,127),MAX(chan[i].portaSpeed,0)));
|
||||||
chan[i].portaStop=true;
|
chan[i].portaStop=true;
|
||||||
chan[i].nowYouCanStop=false;
|
chan[i].nowYouCanStop=false;
|
||||||
chan[i].stopOnOff=song.stopPortaOnNoteOff; // what?!
|
chan[i].stopOnOff=song.stopPortaOnNoteOff; // what?!
|
||||||
|
@ -789,7 +789,7 @@ void DivEngine::processRow(int i, bool afterDelay) {
|
||||||
case 0xe2: // portamento down
|
case 0xe2: // portamento down
|
||||||
chan[i].portaNote=chan[i].note-(effectVal&15);
|
chan[i].portaNote=chan[i].note-(effectVal&15);
|
||||||
chan[i].portaSpeed=(effectVal>>4)*4;
|
chan[i].portaSpeed=(effectVal>>4)*4;
|
||||||
dispatchCmd(DivCommand(DIV_CMD_HINT_PORTA,i,chan[i].portaNote,chan[i].portaSpeed));
|
dispatchCmd(DivCommand(DIV_CMD_HINT_PORTA,i,CLAMP(chan[i].portaNote,-128,127),MAX(chan[i].portaSpeed,0)));
|
||||||
chan[i].portaStop=true;
|
chan[i].portaStop=true;
|
||||||
chan[i].nowYouCanStop=false;
|
chan[i].nowYouCanStop=false;
|
||||||
chan[i].stopOnOff=song.stopPortaOnNoteOff; // what?!
|
chan[i].stopOnOff=song.stopPortaOnNoteOff; // what?!
|
||||||
|
@ -947,13 +947,13 @@ void DivEngine::processRow(int i, bool afterDelay) {
|
||||||
if (chan[i].inPorta && chan[i].keyOn && !chan[i].shorthandPorta) {
|
if (chan[i].inPorta && chan[i].keyOn && !chan[i].shorthandPorta) {
|
||||||
if (song.e1e2StopOnSameNote && chan[i].wasShorthandPorta) {
|
if (song.e1e2StopOnSameNote && chan[i].wasShorthandPorta) {
|
||||||
chan[i].portaSpeed=-1;
|
chan[i].portaSpeed=-1;
|
||||||
dispatchCmd(DivCommand(DIV_CMD_HINT_PORTA,i,chan[i].portaNote,chan[i].portaSpeed));
|
dispatchCmd(DivCommand(DIV_CMD_HINT_PORTA,i,CLAMP(chan[i].portaNote,-128,127),MAX(chan[i].portaSpeed,0)));
|
||||||
if (!song.brokenShortcutSlides) dispatchCmd(DivCommand(DIV_CMD_PRE_PORTA,i,false,0));
|
if (!song.brokenShortcutSlides) dispatchCmd(DivCommand(DIV_CMD_PRE_PORTA,i,false,0));
|
||||||
chan[i].wasShorthandPorta=false;
|
chan[i].wasShorthandPorta=false;
|
||||||
chan[i].inPorta=false;
|
chan[i].inPorta=false;
|
||||||
} else {
|
} else {
|
||||||
chan[i].portaNote=chan[i].note;
|
chan[i].portaNote=chan[i].note;
|
||||||
dispatchCmd(DivCommand(DIV_CMD_HINT_PORTA,i,chan[i].portaNote,chan[i].portaSpeed));
|
dispatchCmd(DivCommand(DIV_CMD_HINT_PORTA,i,CLAMP(chan[i].portaNote,-128,127),MAX(chan[i].portaSpeed,0)));
|
||||||
}
|
}
|
||||||
} else if (!chan[i].noteOnInhibit) {
|
} else if (!chan[i].noteOnInhibit) {
|
||||||
dispatchCmd(DivCommand(DIV_CMD_NOTE_ON,i,chan[i].note,chan[i].volume>>8));
|
dispatchCmd(DivCommand(DIV_CMD_NOTE_ON,i,chan[i].note,chan[i].volume>>8));
|
||||||
|
@ -966,7 +966,7 @@ void DivEngine::processRow(int i, bool afterDelay) {
|
||||||
if (!chan[i].keyOn && chan[i].scheduledSlideReset) {
|
if (!chan[i].keyOn && chan[i].scheduledSlideReset) {
|
||||||
chan[i].portaNote=-1;
|
chan[i].portaNote=-1;
|
||||||
chan[i].portaSpeed=-1;
|
chan[i].portaSpeed=-1;
|
||||||
dispatchCmd(DivCommand(DIV_CMD_HINT_PORTA,i,chan[i].portaNote,chan[i].portaSpeed));
|
dispatchCmd(DivCommand(DIV_CMD_HINT_PORTA,i,CLAMP(chan[i].portaNote,-128,127),MAX(chan[i].portaSpeed,0)));
|
||||||
chan[i].scheduledSlideReset=false;
|
chan[i].scheduledSlideReset=false;
|
||||||
chan[i].inPorta=false;
|
chan[i].inPorta=false;
|
||||||
}
|
}
|
||||||
|
@ -1311,7 +1311,7 @@ bool DivEngine::nextTick(bool noAccum, bool inhibitLowLat) {
|
||||||
if ((chan[i].keyOn || chan[i].keyOff) && chan[i].portaSpeed>0) {
|
if ((chan[i].keyOn || chan[i].keyOff) && chan[i].portaSpeed>0) {
|
||||||
if (dispatchCmd(DivCommand(DIV_CMD_NOTE_PORTA,i,chan[i].portaSpeed*(song.linearPitch==2?song.pitchSlideSpeed:1),chan[i].portaNote))==2 && chan[i].portaStop && song.targetResetsSlides) {
|
if (dispatchCmd(DivCommand(DIV_CMD_NOTE_PORTA,i,chan[i].portaSpeed*(song.linearPitch==2?song.pitchSlideSpeed:1),chan[i].portaNote))==2 && chan[i].portaStop && song.targetResetsSlides) {
|
||||||
chan[i].portaSpeed=0;
|
chan[i].portaSpeed=0;
|
||||||
dispatchCmd(DivCommand(DIV_CMD_HINT_PORTA,i,chan[i].portaNote,chan[i].portaSpeed));
|
dispatchCmd(DivCommand(DIV_CMD_HINT_PORTA,i,CLAMP(chan[i].portaNote,-128,127),MAX(chan[i].portaSpeed,0)));
|
||||||
chan[i].oldNote=chan[i].note;
|
chan[i].oldNote=chan[i].note;
|
||||||
chan[i].note=chan[i].portaNote;
|
chan[i].note=chan[i].portaNote;
|
||||||
chan[i].inPorta=false;
|
chan[i].inPorta=false;
|
||||||
|
@ -1330,13 +1330,13 @@ bool DivEngine::nextTick(bool noAccum, bool inhibitLowLat) {
|
||||||
if (chan[i].stopOnOff) {
|
if (chan[i].stopOnOff) {
|
||||||
chan[i].portaNote=-1;
|
chan[i].portaNote=-1;
|
||||||
chan[i].portaSpeed=-1;
|
chan[i].portaSpeed=-1;
|
||||||
dispatchCmd(DivCommand(DIV_CMD_HINT_PORTA,i,chan[i].portaNote,chan[i].portaSpeed));
|
dispatchCmd(DivCommand(DIV_CMD_HINT_PORTA,i,CLAMP(chan[i].portaNote,-128,127),MAX(chan[i].portaSpeed,0)));
|
||||||
chan[i].stopOnOff=false;
|
chan[i].stopOnOff=false;
|
||||||
}
|
}
|
||||||
if (disCont[dispatchOfChan[i]].dispatch->keyOffAffectsPorta(dispatchChanOfChan[i])) {
|
if (disCont[dispatchOfChan[i]].dispatch->keyOffAffectsPorta(dispatchChanOfChan[i])) {
|
||||||
chan[i].portaNote=-1;
|
chan[i].portaNote=-1;
|
||||||
chan[i].portaSpeed=-1;
|
chan[i].portaSpeed=-1;
|
||||||
dispatchCmd(DivCommand(DIV_CMD_HINT_PORTA,i,chan[i].portaNote,chan[i].portaSpeed));
|
dispatchCmd(DivCommand(DIV_CMD_HINT_PORTA,i,CLAMP(chan[i].portaNote,-128,127),MAX(chan[i].portaSpeed,0)));
|
||||||
/*if (i==2 && sysOfChan[i]==DIV_SYSTEM_SMS) {
|
/*if (i==2 && sysOfChan[i]==DIV_SYSTEM_SMS) {
|
||||||
chan[i+1].portaNote=-1;
|
chan[i+1].portaNote=-1;
|
||||||
chan[i+1].portaSpeed=-1;
|
chan[i+1].portaSpeed=-1;
|
||||||
|
|
Loading…
Reference in New Issue