parent
ff07a19405
commit
0f3f173b6e
|
@ -15,6 +15,7 @@ enum DivDispatchCmds {
|
|||
DIV_CMD_PANNING,
|
||||
DIV_CMD_LEGATO,
|
||||
DIV_CMD_PRE_PORTA,
|
||||
DIV_CMD_PRE_NOTE, // used in C64
|
||||
|
||||
DIV_CMD_SAMPLE_MODE,
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ struct DivChannelState {
|
|||
std::vector<DivDelayedCommand> delayed;
|
||||
int note, pitch, portaSpeed, portaNote;
|
||||
int volume, volSpeed, cut, rowDelay, volMax;
|
||||
int delayOrder, delayRow;
|
||||
int vibratoDepth, vibratoRate, vibratoPos, vibratoDir, vibratoFine;
|
||||
int tremoloDepth, tremoloRate, tremoloPos;
|
||||
unsigned char arp, arpStage, arpTicks;
|
||||
|
@ -34,6 +35,8 @@ struct DivChannelState {
|
|||
volSpeed(0),
|
||||
cut(-1),
|
||||
rowDelay(0),
|
||||
delayOrder(0),
|
||||
delayRow(0),
|
||||
vibratoDepth(0),
|
||||
vibratoRate(0),
|
||||
vibratoPos(0),
|
||||
|
@ -104,7 +107,7 @@ class DivEngine {
|
|||
speedAB(false),
|
||||
ticks(0),
|
||||
cycles(0),
|
||||
curRow(-1),
|
||||
curRow(0),
|
||||
curOrder(0),
|
||||
changeOrd(-1),
|
||||
changePos(0),
|
||||
|
|
|
@ -10,31 +10,6 @@ void DivPlatformC64::acquire(int& l, int& r) {
|
|||
r=l;
|
||||
}
|
||||
|
||||
static unsigned char noiseTable[256]={
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 4,
|
||||
15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4,
|
||||
15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4,
|
||||
3, 2, 1, 0, 11, 10, 9, 8, 7, 6, 5, 4,
|
||||
15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4,
|
||||
3, 2, 1, 0, 11, 10, 9, 8, 7, 6, 5, 4,
|
||||
15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4,
|
||||
3, 2, 1, 0, 11, 10, 9, 8, 7, 6, 5, 4,
|
||||
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
|
||||
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
|
||||
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
|
||||
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
|
||||
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
|
||||
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
|
||||
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
|
||||
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
|
||||
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
|
||||
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
|
||||
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
|
||||
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
|
||||
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
|
||||
15
|
||||
};
|
||||
|
||||
void DivPlatformC64::tick() {
|
||||
for (int i=0; i<3; i++) {
|
||||
chan[i].std.next();
|
||||
|
@ -84,16 +59,10 @@ void DivPlatformC64::tick() {
|
|||
//rWrite(16+i*5,chan[i].sweep);
|
||||
}
|
||||
}
|
||||
if (chan[i].onTheKey) {
|
||||
DivInstrument* ins=parent->getIns(chan[i].ins);
|
||||
sid.write(i*7+4,
|
||||
(ins->c64.noiseOn<<7)|
|
||||
(ins->c64.pulseOn<<6)|
|
||||
(ins->c64.sawOn<<5)|
|
||||
(ins->c64.triOn<<4)|
|
||||
1
|
||||
);
|
||||
chan[i].onTheKey=false;
|
||||
if (chan[i].testWhen>0) {
|
||||
if (--chan[i].testWhen<1) {
|
||||
sid.write(i*7+4,8);
|
||||
}
|
||||
}
|
||||
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
||||
DivInstrument* ins=parent->getIns(chan[i].ins);
|
||||
|
@ -106,9 +75,8 @@ void DivPlatformC64::tick() {
|
|||
(ins->c64.pulseOn<<6)|
|
||||
(ins->c64.sawOn<<5)|
|
||||
(ins->c64.triOn<<4)|
|
||||
8
|
||||
1
|
||||
);
|
||||
chan[i].onTheKey=true;
|
||||
}
|
||||
if (chan[i].keyOff) {
|
||||
sid.write(i*7+5,(ins->c64.a<<4)|(ins->c64.d));
|
||||
|
@ -207,6 +175,9 @@ int DivPlatformC64::dispatch(DivCommand c) {
|
|||
chan[c.chan].std.init(parent->getIns(chan[c.chan].ins));
|
||||
chan[c.chan].inPorta=c.value;
|
||||
break;
|
||||
case DIV_CMD_PRE_NOTE:
|
||||
chan[c.chan].testWhen=c.value;
|
||||
break;
|
||||
case DIV_CMD_GET_VOLMAX:
|
||||
return 15;
|
||||
break;
|
||||
|
|
|
@ -7,9 +7,9 @@
|
|||
|
||||
class DivPlatformC64: public DivDispatch {
|
||||
struct Channel {
|
||||
int freq, baseFreq, pitch, prevFreq;
|
||||
int freq, baseFreq, pitch, prevFreq, testWhen;
|
||||
unsigned char ins, note, duty, sweep;
|
||||
bool active, insChanged, freqChanged, sweepChanged, keyOn, keyOff, inPorta, onTheKey;
|
||||
bool active, insChanged, freqChanged, sweepChanged, keyOn, keyOff, inPorta;
|
||||
signed char vol, outVol, wave;
|
||||
DivMacroInt std;
|
||||
Channel():
|
||||
|
@ -17,6 +17,7 @@ class DivPlatformC64: public DivDispatch {
|
|||
baseFreq(0),
|
||||
pitch(0),
|
||||
prevFreq(65535),
|
||||
testWhen(0),
|
||||
ins(-1),
|
||||
note(0),
|
||||
duty(0),
|
||||
|
@ -28,7 +29,6 @@ class DivPlatformC64: public DivDispatch {
|
|||
keyOn(false),
|
||||
keyOff(false),
|
||||
inPorta(false),
|
||||
onTheKey(false),
|
||||
vol(15),
|
||||
wave(-1) {}
|
||||
};
|
||||
|
|
|
@ -23,6 +23,7 @@ const char* cmdName[DIV_CMD_MAX]={
|
|||
"PANNING",
|
||||
"LEGATO",
|
||||
"PRE_PORTA",
|
||||
"PRE_NOTE",
|
||||
|
||||
"SAMPLE_MODE",
|
||||
|
||||
|
@ -205,25 +206,29 @@ bool DivEngine::perSystemPostEffect(int ch, unsigned char effect, unsigned char
|
|||
}
|
||||
|
||||
void DivEngine::processRow(int i, bool afterDelay) {
|
||||
DivPattern* pat=song.pat[i]->data[curOrder];
|
||||
int whatOrder=afterDelay?chan[i].delayOrder:curOrder;
|
||||
int whatRow=afterDelay?chan[i].delayRow:curRow;
|
||||
DivPattern* pat=song.pat[i]->data[whatOrder];
|
||||
// pre effects
|
||||
if (!afterDelay) for (int j=0; j<song.pat[i]->effectRows; j++) {
|
||||
short effect=pat->data[curRow][4+(j<<1)];
|
||||
short effectVal=pat->data[curRow][5+(j<<1)];
|
||||
short effect=pat->data[whatRow][4+(j<<1)];
|
||||
short effectVal=pat->data[whatRow][5+(j<<1)];
|
||||
|
||||
if (effectVal==-1) effectVal=0;
|
||||
if (effect==0xed) {
|
||||
chan[i].rowDelay=effectVal+1;
|
||||
chan[i].delayOrder=whatOrder;
|
||||
chan[i].delayRow=whatRow;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// instrument
|
||||
if (pat->data[curRow][2]!=-1) {
|
||||
dispatchCmd(DivCommand(DIV_CMD_INSTRUMENT,i,pat->data[curRow][2]));
|
||||
if (pat->data[whatRow][2]!=-1) {
|
||||
dispatchCmd(DivCommand(DIV_CMD_INSTRUMENT,i,pat->data[whatRow][2]));
|
||||
}
|
||||
// note
|
||||
if (pat->data[curRow][0]==100) {
|
||||
if (pat->data[whatRow][0]==100) {
|
||||
chan[i].note=-1;
|
||||
chan[i].keyOn=false;
|
||||
if (chan[i].stopOnOff) {
|
||||
|
@ -232,8 +237,8 @@ void DivEngine::processRow(int i, bool afterDelay) {
|
|||
chan[i].stopOnOff=false;
|
||||
}
|
||||
dispatchCmd(DivCommand(DIV_CMD_NOTE_OFF,i));
|
||||
} else if (!(pat->data[curRow][0]==0 && pat->data[curRow][1]==0)) {
|
||||
chan[i].note=pat->data[curRow][0]+pat->data[curRow][1]*12;
|
||||
} else if (!(pat->data[whatRow][0]==0 && pat->data[whatRow][1]==0)) {
|
||||
chan[i].note=pat->data[whatRow][0]+pat->data[whatRow][1]*12;
|
||||
if (!chan[i].keyOn) {
|
||||
chan[i].arp=0;
|
||||
}
|
||||
|
@ -244,17 +249,17 @@ void DivEngine::processRow(int i, bool afterDelay) {
|
|||
}
|
||||
|
||||
// volume
|
||||
if (pat->data[curRow][3]!=-1) {
|
||||
if (dispatchCmd(DivCommand(DIV_ALWAYS_SET_VOLUME,i)) || (MIN(chan[i].volMax,chan[i].volume)>>8)!=pat->data[curRow][3]) {
|
||||
chan[i].volume=pat->data[curRow][3]<<8;
|
||||
if (pat->data[whatRow][3]!=-1) {
|
||||
if (dispatchCmd(DivCommand(DIV_ALWAYS_SET_VOLUME,i)) || (MIN(chan[i].volMax,chan[i].volume)>>8)!=pat->data[whatRow][3]) {
|
||||
chan[i].volume=pat->data[whatRow][3]<<8;
|
||||
dispatchCmd(DivCommand(DIV_CMD_VOLUME,i,chan[i].volume>>8));
|
||||
}
|
||||
}
|
||||
|
||||
// effects
|
||||
for (int j=0; j<song.pat[i]->effectRows; j++) {
|
||||
short effect=pat->data[curRow][4+(j<<1)];
|
||||
short effectVal=pat->data[curRow][5+(j<<1)];
|
||||
short effect=pat->data[whatRow][4+(j<<1)];
|
||||
short effectVal=pat->data[whatRow][5+(j<<1)];
|
||||
|
||||
if (effectVal==-1) effectVal=0;
|
||||
|
||||
|
@ -336,6 +341,8 @@ void DivEngine::processRow(int i, bool afterDelay) {
|
|||
break;
|
||||
case 0x0c: // retrigger
|
||||
chan[i].rowDelay=effectVal+1;
|
||||
chan[i].delayOrder=whatOrder;
|
||||
chan[i].delayRow=whatRow;
|
||||
break;
|
||||
|
||||
case 0xe0: // arp speed
|
||||
|
@ -399,8 +406,8 @@ void DivEngine::processRow(int i, bool afterDelay) {
|
|||
|
||||
// post effects
|
||||
for (int j=0; j<song.pat[i]->effectRows; j++) {
|
||||
short effect=pat->data[curRow][4+(j<<1)];
|
||||
short effectVal=pat->data[curRow][5+(j<<1)];
|
||||
short effect=pat->data[whatRow][4+(j<<1)];
|
||||
short effectVal=pat->data[whatRow][5+(j<<1)];
|
||||
|
||||
if (effectVal==-1) effectVal=0;
|
||||
perSystemPostEffect(i,effect,effectVal);
|
||||
|
@ -412,18 +419,6 @@ void DivEngine::nextRow() {
|
|||
static char pb1[4096];
|
||||
static char pb2[4096];
|
||||
static char pb3[4096];
|
||||
if (++curRow>=song.patLen) {
|
||||
nextOrder();
|
||||
}
|
||||
if (changeOrd>=0) {
|
||||
curRow=changePos;
|
||||
curOrder=changeOrd;
|
||||
if (curOrder>=song.ordersLen) {
|
||||
curOrder=0;
|
||||
}
|
||||
changeOrd=-1;
|
||||
}
|
||||
|
||||
if (view==DIV_STATUS_PATTERN) {
|
||||
strcpy(pb1,"");
|
||||
strcpy(pb3,"");
|
||||
|
@ -469,6 +464,33 @@ void DivEngine::nextRow() {
|
|||
chan[i].rowDelay=0;
|
||||
processRow(i,false);
|
||||
}
|
||||
|
||||
if (++curRow>=song.patLen) {
|
||||
nextOrder();
|
||||
}
|
||||
if (changeOrd>=0) {
|
||||
curRow=changePos;
|
||||
curOrder=changeOrd;
|
||||
if (curOrder>=song.ordersLen) {
|
||||
curOrder=0;
|
||||
}
|
||||
changeOrd=-1;
|
||||
}
|
||||
|
||||
if (speedAB) {
|
||||
ticks=song.speed2*(song.timeBase+1);
|
||||
} else {
|
||||
ticks=song.speed1*(song.timeBase+1);
|
||||
}
|
||||
speedAB=!speedAB;
|
||||
|
||||
// post row details
|
||||
for (int i=0; i<chans; i++) {
|
||||
DivPattern* pat=song.pat[i]->data[curOrder];
|
||||
if (!(pat->data[curRow][0]==0 && pat->data[curRow][1]==0)) {
|
||||
dispatchCmd(DivCommand(DIV_CMD_PRE_NOTE,i,ticks));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DivEngine::nextTick() {
|
||||
|
@ -483,12 +505,6 @@ void DivEngine::nextTick() {
|
|||
}
|
||||
if (--ticks<=0) {
|
||||
nextRow();
|
||||
if (speedAB) {
|
||||
ticks=song.speed2*(song.timeBase+1);
|
||||
} else {
|
||||
ticks=song.speed1*(song.timeBase+1);
|
||||
}
|
||||
speedAB=!speedAB;
|
||||
}
|
||||
// process stuff
|
||||
for (int i=0; i<chans; i++) {
|
||||
|
|
Loading…
Reference in New Issue