implement command playback - UNTESTED!
This commit is contained in:
parent
d7922baa07
commit
6fba60818d
|
@ -223,7 +223,6 @@ bool DivCSPlayer::tick() {
|
||||||
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_VOLUME:
|
case DIV_CMD_HINT_VOLUME:
|
||||||
case DIV_CMD_HINT_ARP_TIME:
|
|
||||||
arg0=(unsigned char)stream.readC();
|
arg0=(unsigned char)stream.readC();
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_HINT_PITCH:
|
case DIV_CMD_HINT_PITCH:
|
||||||
|
@ -259,14 +258,16 @@ bool DivCSPlayer::tick() {
|
||||||
arg0-=60;
|
arg0-=60;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
// ONE BYTE COMMANDS
|
||||||
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:
|
||||||
case DIV_CMD_SAMPLE_POS:
|
|
||||||
case DIV_CMD_SAMPLE_DIR:
|
case DIV_CMD_SAMPLE_DIR:
|
||||||
case DIV_CMD_FM_HARD_RESET:
|
case DIV_CMD_FM_HARD_RESET:
|
||||||
case DIV_CMD_FM_LFO:
|
case DIV_CMD_FM_LFO:
|
||||||
case DIV_CMD_FM_LFO_WAVE:
|
case DIV_CMD_FM_LFO_WAVE:
|
||||||
|
case DIV_CMD_FM_LFO2:
|
||||||
|
case DIV_CMD_FM_LFO2_WAVE:
|
||||||
case DIV_CMD_FM_FB:
|
case DIV_CMD_FM_FB:
|
||||||
case DIV_CMD_FM_EXTCH:
|
case DIV_CMD_FM_EXTCH:
|
||||||
case DIV_CMD_FM_AM_DEPTH:
|
case DIV_CMD_FM_AM_DEPTH:
|
||||||
|
@ -306,8 +307,101 @@ bool DivCSPlayer::tick() {
|
||||||
case DIV_CMD_MACRO_OFF:
|
case DIV_CMD_MACRO_OFF:
|
||||||
case DIV_CMD_MACRO_ON:
|
case DIV_CMD_MACRO_ON:
|
||||||
case DIV_CMD_MACRO_RESTART:
|
case DIV_CMD_MACRO_RESTART:
|
||||||
|
case DIV_CMD_HINT_ARP_TIME:
|
||||||
|
case DIV_CMD_QSOUND_ECHO_FEEDBACK:
|
||||||
|
case DIV_CMD_QSOUND_ECHO_LEVEL:
|
||||||
|
case DIV_CMD_QSOUND_SURROUND:
|
||||||
|
case DIV_CMD_X1_010_ENVELOPE_SHAPE:
|
||||||
|
case DIV_CMD_X1_010_ENVELOPE_ENABLE:
|
||||||
|
case DIV_CMD_X1_010_ENVELOPE_MODE:
|
||||||
|
case DIV_CMD_X1_010_ENVELOPE_PERIOD:
|
||||||
|
case DIV_CMD_X1_010_ENVELOPE_SLIDE:
|
||||||
|
case DIV_CMD_X1_010_AUTO_ENVELOPE:
|
||||||
|
case DIV_CMD_X1_010_SAMPLE_BANK_SLOT:
|
||||||
|
case DIV_CMD_WS_SWEEP_TIME:
|
||||||
|
case DIV_CMD_WS_SWEEP_AMOUNT:
|
||||||
|
case DIV_CMD_N163_WAVE_POSITION:
|
||||||
|
case DIV_CMD_N163_WAVE_LENGTH:
|
||||||
|
case DIV_CMD_N163_WAVE_UNUSED1:
|
||||||
|
case DIV_CMD_N163_WAVE_UNUSED2:
|
||||||
|
case DIV_CMD_N163_WAVE_LOADPOS:
|
||||||
|
case DIV_CMD_N163_WAVE_LOADLEN:
|
||||||
|
case DIV_CMD_N163_WAVE_UNUSED3:
|
||||||
|
case DIV_CMD_N163_CHANNEL_LIMIT:
|
||||||
|
case DIV_CMD_N163_GLOBAL_WAVE_LOAD:
|
||||||
|
case DIV_CMD_N163_GLOBAL_WAVE_LOADPOS:
|
||||||
|
case DIV_CMD_N163_UNUSED4:
|
||||||
|
case DIV_CMD_N163_UNUSED5:
|
||||||
|
case DIV_CMD_SU_SYNC_PERIOD_LOW:
|
||||||
|
case DIV_CMD_SU_SYNC_PERIOD_HIGH:
|
||||||
|
case DIV_CMD_ADPCMA_GLOBAL_VOLUME:
|
||||||
|
case DIV_CMD_SNES_ECHO:
|
||||||
|
case DIV_CMD_SNES_PITCH_MOD:
|
||||||
|
case DIV_CMD_SNES_INVERT:
|
||||||
|
case DIV_CMD_SNES_GAIN_MODE:
|
||||||
|
case DIV_CMD_SNES_GAIN:
|
||||||
|
case DIV_CMD_SNES_ECHO_ENABLE:
|
||||||
|
case DIV_CMD_SNES_ECHO_DELAY:
|
||||||
|
case DIV_CMD_SNES_ECHO_VOL_LEFT:
|
||||||
|
case DIV_CMD_SNES_ECHO_VOL_RIGHT:
|
||||||
|
case DIV_CMD_SNES_ECHO_FEEDBACK:
|
||||||
|
case DIV_CMD_NES_ENV_MODE:
|
||||||
|
case DIV_CMD_NES_LENGTH:
|
||||||
|
case DIV_CMD_NES_COUNT_MODE:
|
||||||
|
case DIV_CMD_FM_AM2_DEPTH:
|
||||||
|
case DIV_CMD_FM_PM2_DEPTH:
|
||||||
|
case DIV_CMD_ES5506_ENVELOPE_LVRAMP:
|
||||||
|
case DIV_CMD_ES5506_ENVELOPE_RVRAMP:
|
||||||
|
case DIV_CMD_ES5506_PAUSE:
|
||||||
|
case DIV_CMD_ES5506_FILTER_MODE:
|
||||||
|
case DIV_CMD_SNES_GLOBAL_VOL_LEFT:
|
||||||
|
case DIV_CMD_SNES_GLOBAL_VOL_RIGHT:
|
||||||
|
case DIV_CMD_NES_LINEAR_LENGTH:
|
||||||
|
case DIV_CMD_EXTERNAL:
|
||||||
|
case DIV_CMD_C64_AD:
|
||||||
|
case DIV_CMD_C64_SR:
|
||||||
|
case DIV_CMD_DAVE_HIGH_PASS:
|
||||||
|
case DIV_CMD_DAVE_RING_MOD:
|
||||||
|
case DIV_CMD_DAVE_SWAP_COUNTERS:
|
||||||
|
case DIV_CMD_DAVE_LOW_PASS:
|
||||||
|
case DIV_CMD_DAVE_CLOCK_DIV:
|
||||||
|
case DIV_CMD_MINMOD_ECHO:
|
||||||
|
case DIV_CMD_FDS_MOD_AUTO:
|
||||||
|
case DIV_CMD_FM_OPMASK:
|
||||||
|
case DIV_CMD_MULTIPCM_MIX_FM:
|
||||||
|
case DIV_CMD_MULTIPCM_MIX_PCM:
|
||||||
|
case DIV_CMD_MULTIPCM_LFO:
|
||||||
|
case DIV_CMD_MULTIPCM_VIB:
|
||||||
|
case DIV_CMD_MULTIPCM_AM:
|
||||||
|
case DIV_CMD_MULTIPCM_AR:
|
||||||
|
case DIV_CMD_MULTIPCM_D1R:
|
||||||
|
case DIV_CMD_MULTIPCM_DL:
|
||||||
|
case DIV_CMD_MULTIPCM_D2R:
|
||||||
|
case DIV_CMD_MULTIPCM_RC:
|
||||||
|
case DIV_CMD_MULTIPCM_RR:
|
||||||
|
case DIV_CMD_MULTIPCM_DAMP:
|
||||||
|
case DIV_CMD_MULTIPCM_PSEUDO_REVERB:
|
||||||
|
case DIV_CMD_MULTIPCM_LFO_RESET:
|
||||||
|
case DIV_CMD_MULTIPCM_LEVEL_DIRECT:
|
||||||
|
case DIV_CMD_SID3_SPECIAL_WAVE:
|
||||||
|
case DIV_CMD_SID3_RING_MOD_SRC:
|
||||||
|
case DIV_CMD_SID3_HARD_SYNC_SRC:
|
||||||
|
case DIV_CMD_SID3_PHASE_MOD_SRC:
|
||||||
|
case DIV_CMD_SID3_WAVE_MIX:
|
||||||
|
case DIV_CMD_SID3_1_BIT_NOISE:
|
||||||
|
case DIV_CMD_SID3_CHANNEL_INVERSION:
|
||||||
|
case DIV_CMD_SID3_FILTER_CONNECTION:
|
||||||
|
case DIV_CMD_SID3_FILTER_MATRIX:
|
||||||
|
case DIV_CMD_SID3_FILTER_ENABLE:
|
||||||
|
case DIV_CMD_SID3_PHASE_RESET:
|
||||||
|
case DIV_CMD_SID3_NOISE_PHASE_RESET:
|
||||||
|
case DIV_CMD_SID3_ENVELOPE_RESET:
|
||||||
|
case DIV_CMD_SID3_CUTOFF_SCALING:
|
||||||
|
case DIV_CMD_SID3_RESONANCE_SCALING:
|
||||||
|
case DIV_CMD_WS_GLOBAL_SPEAKER_VOLUME:
|
||||||
arg0=(unsigned char)stream.readC();
|
arg0=(unsigned char)stream.readC();
|
||||||
break;
|
break;
|
||||||
|
// TWO BYTE COMMANDS
|
||||||
case DIV_CMD_FM_TL:
|
case DIV_CMD_FM_TL:
|
||||||
case DIV_CMD_FM_AM:
|
case DIV_CMD_FM_AM:
|
||||||
case DIV_CMD_FM_AR:
|
case DIV_CMD_FM_AR:
|
||||||
|
@ -330,14 +424,45 @@ bool DivCSPlayer::tick() {
|
||||||
case DIV_CMD_AY_IO_WRITE:
|
case DIV_CMD_AY_IO_WRITE:
|
||||||
case DIV_CMD_AY_AUTO_PWM:
|
case DIV_CMD_AY_AUTO_PWM:
|
||||||
case DIV_CMD_SURROUND_PANNING:
|
case DIV_CMD_SURROUND_PANNING:
|
||||||
|
case DIV_CMD_SU_SWEEP_PERIOD_LOW:
|
||||||
|
case DIV_CMD_SU_SWEEP_PERIOD_HIGH:
|
||||||
|
case DIV_CMD_SU_SWEEP_BOUND:
|
||||||
|
case DIV_CMD_SU_SWEEP_ENABLE:
|
||||||
|
case DIV_CMD_SNES_ECHO_FIR:
|
||||||
|
case DIV_CMD_ES5506_FILTER_K1_SLIDE:
|
||||||
|
case DIV_CMD_ES5506_FILTER_K2_SLIDE:
|
||||||
|
case DIV_CMD_ES5506_ENVELOPE_K1RAMP:
|
||||||
|
case DIV_CMD_ES5506_ENVELOPE_K2RAMP:
|
||||||
|
case DIV_CMD_ESFM_OP_PANNING:
|
||||||
|
case DIV_CMD_ESFM_OUTLVL:
|
||||||
|
case DIV_CMD_ESFM_MODIN:
|
||||||
|
case DIV_CMD_ESFM_ENV_DELAY:
|
||||||
|
case DIV_CMD_POWERNOISE_COUNTER_LOAD:
|
||||||
|
case DIV_CMD_POWERNOISE_IO_WRITE:
|
||||||
|
case DIV_CMD_BIFURCATOR_STATE_LOAD:
|
||||||
|
case DIV_CMD_BIFURCATOR_PARAMETER:
|
||||||
|
case DIV_CMD_SID3_LFSR_FEEDBACK_BITS:
|
||||||
|
case DIV_CMD_SID3_FILTER_DISTORTION:
|
||||||
|
case DIV_CMD_SID3_FILTER_OUTPUT_VOLUME:
|
||||||
|
case DIV_CMD_C64_PW_SLIDE:
|
||||||
|
case DIV_CMD_C64_CUTOFF_SLIDE:
|
||||||
arg0=(unsigned char)stream.readC();
|
arg0=(unsigned char)stream.readC();
|
||||||
arg1=(unsigned char)stream.readC();
|
arg1=(unsigned char)stream.readC();
|
||||||
break;
|
break;
|
||||||
|
// ONE SHORT COMMANDS
|
||||||
case DIV_CMD_C64_FINE_DUTY:
|
case DIV_CMD_C64_FINE_DUTY:
|
||||||
case DIV_CMD_C64_FINE_CUTOFF:
|
case DIV_CMD_C64_FINE_CUTOFF:
|
||||||
case DIV_CMD_LYNX_LFSR_LOAD:
|
case DIV_CMD_LYNX_LFSR_LOAD:
|
||||||
|
case DIV_CMD_QSOUND_ECHO_DELAY:
|
||||||
|
case DIV_CMD_ES5506_ENVELOPE_COUNT:
|
||||||
arg0=(unsigned short)stream.readS();
|
arg0=(unsigned short)stream.readS();
|
||||||
break;
|
break;
|
||||||
|
// TWO SHORT COMMANDS
|
||||||
|
case DIV_CMD_ES5506_FILTER_K1:
|
||||||
|
case DIV_CMD_ES5506_FILTER_K2:
|
||||||
|
arg0=(unsigned short)stream.readS();
|
||||||
|
arg1=(unsigned short)stream.readS();
|
||||||
|
break;
|
||||||
case DIV_CMD_FM_FIXFREQ:
|
case DIV_CMD_FM_FIXFREQ:
|
||||||
arg0=(unsigned short)stream.readS();
|
arg0=(unsigned short)stream.readS();
|
||||||
arg1=arg0&0x7ff;
|
arg1=arg0&0x7ff;
|
||||||
|
@ -348,6 +473,9 @@ bool DivCSPlayer::tick() {
|
||||||
arg1=arg0&0x77;
|
arg1=arg0&0x77;
|
||||||
arg0=(arg0&8)?1:0;
|
arg0=(arg0&8)?1:0;
|
||||||
break;
|
break;
|
||||||
|
case DIV_CMD_SAMPLE_POS:
|
||||||
|
arg0=(unsigned int)stream.readI();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (command) {
|
switch (command) {
|
||||||
|
|
|
@ -913,7 +913,32 @@ SafeWriter* DivEngine::saveCommand() {
|
||||||
extValuePresent=false;
|
extValuePresent=false;
|
||||||
BUSY_END;
|
BUSY_END;
|
||||||
|
|
||||||
// PASS 1: condense delays
|
// PASS 1: optimize command calls
|
||||||
|
// calculate command usage
|
||||||
|
int sortCand=-1;
|
||||||
|
int sortPos=0;
|
||||||
|
while (sortPos<16) {
|
||||||
|
sortCand=-1;
|
||||||
|
for (int i=DIV_CMD_SAMPLE_MODE; i<256; i++) {
|
||||||
|
if (cmdPopularity[i]) {
|
||||||
|
if (sortCand==-1) {
|
||||||
|
sortCand=i;
|
||||||
|
} else if (cmdPopularity[sortCand]<cmdPopularity[i]) {
|
||||||
|
sortCand=i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sortCand==-1) break;
|
||||||
|
|
||||||
|
sortedCmdPopularity[sortPos]=cmdPopularity[sortCand];
|
||||||
|
sortedCmd[sortPos]=sortCand;
|
||||||
|
cmdPopularity[sortCand]=0;
|
||||||
|
sortPos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set speed dial commands (TODO)
|
||||||
|
|
||||||
|
// PASS 2: condense delays
|
||||||
// calculate delay usage
|
// calculate delay usage
|
||||||
for (int h=0; h<chans; h++) {
|
for (int h=0; h<chans; h++) {
|
||||||
unsigned char* buf=chanStream[h]->getFinalBuf();
|
unsigned char* buf=chanStream[h]->getFinalBuf();
|
||||||
|
@ -937,8 +962,8 @@ SafeWriter* DivEngine::saveCommand() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// preset delays
|
// preset delays
|
||||||
int sortCand=-1;
|
sortCand=-1;
|
||||||
int sortPos=0;
|
sortPos=0;
|
||||||
while (sortPos<16) {
|
while (sortPos<16) {
|
||||||
sortCand=-1;
|
sortCand=-1;
|
||||||
for (int i=0; i<256; i++) {
|
for (int i=0; i<256; i++) {
|
||||||
|
@ -1015,14 +1040,14 @@ SafeWriter* DivEngine::saveCommand() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// PASS 2: remove nop's
|
// PASS 3: remove nop's
|
||||||
// this includes modifying call addresses to compensate
|
// this includes modifying call addresses to compensate
|
||||||
for (int h=0; h<chans; h++) {
|
for (int h=0; h<chans; h++) {
|
||||||
chanStream[h]=stripNops(chanStream[h],sortedCmd);
|
chanStream[h]=stripNops(chanStream[h],sortedCmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef DISABLE_BLOCK_SEARCH
|
#ifndef DISABLE_BLOCK_SEARCH
|
||||||
// PASS 3: find sub-blocks and isolate them
|
// PASS 4: find sub-blocks and isolate them
|
||||||
for (int h=0; h<chans; h++) {
|
for (int h=0; h<chans; h++) {
|
||||||
std::vector<SafeWriter*> subBlocks;
|
std::vector<SafeWriter*> subBlocks;
|
||||||
size_t beforeSize=chanStream[h]->size();
|
size_t beforeSize=chanStream[h]->size();
|
||||||
|
@ -1109,34 +1134,11 @@ SafeWriter* DivEngine::saveCommand() {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// PASS 4: remove nop's (again)
|
// PASS 5: remove nop's (again)
|
||||||
for (int h=0; h<chans; h++) {
|
for (int h=0; h<chans; h++) {
|
||||||
chanStream[h]=stripNops(chanStream[h],sortedCmd);
|
chanStream[h]=stripNops(chanStream[h],sortedCmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
// PASS 5: optimize command calls
|
|
||||||
/*
|
|
||||||
int sortCand=-1;
|
|
||||||
int sortPos=0;
|
|
||||||
while (sortPos<16) {
|
|
||||||
sortCand=-1;
|
|
||||||
for (int i=DIV_CMD_SAMPLE_MODE; i<256; i++) {
|
|
||||||
if (cmdPopularity[i]) {
|
|
||||||
if (sortCand==-1) {
|
|
||||||
sortCand=i;
|
|
||||||
} else if (cmdPopularity[sortCand]<cmdPopularity[i]) {
|
|
||||||
sortCand=i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (sortCand==-1) break;
|
|
||||||
|
|
||||||
sortedCmdPopularity[sortPos]=cmdPopularity[sortCand];
|
|
||||||
sortedCmd[sortPos]=sortCand;
|
|
||||||
cmdPopularity[sortCand]=0;
|
|
||||||
sortPos++;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
// write results
|
// write results
|
||||||
for (int i=0; i<chans; i++) {
|
for (int i=0; i<chans; i++) {
|
||||||
chanStreamOff[i]=w->tell();
|
chanStreamOff[i]=w->tell();
|
||||||
|
|
|
@ -104,6 +104,12 @@ String disasmCmd(unsigned char* buf, size_t bufLen, unsigned int addr) {
|
||||||
if (addr+2>=bufLen) return "???";
|
if (addr+2>=bufLen) return "???";
|
||||||
return fmt::sprintf("pan $%x, $%x",(int)buf[addr+1],(int)buf[addr+2]);
|
return fmt::sprintf("pan $%x, $%x",(int)buf[addr+1],(int)buf[addr+2]);
|
||||||
break;
|
break;
|
||||||
|
case 0xd0: case 0xd1: case 0xd2: case 0xd3:
|
||||||
|
case 0xd4: case 0xd5: case 0xd6: case 0xd7:
|
||||||
|
case 0xd8: case 0xd9: case 0xda: case 0xdb:
|
||||||
|
case 0xdc: case 0xdd: case 0xde: case 0xdf:
|
||||||
|
return "qcmd";
|
||||||
|
break;
|
||||||
case 0xe0: case 0xe1: case 0xe2: case 0xe3:
|
case 0xe0: case 0xe1: case 0xe2: case 0xe3:
|
||||||
case 0xe4: case 0xe5: case 0xe6: case 0xe7:
|
case 0xe4: case 0xe5: case 0xe6: case 0xe7:
|
||||||
case 0xe8: case 0xe9: case 0xea: case 0xeb:
|
case 0xe8: case 0xe9: case 0xea: case 0xeb:
|
||||||
|
@ -129,7 +135,7 @@ String disasmCmd(unsigned char* buf, size_t bufLen, unsigned int addr) {
|
||||||
return fmt::sprintf("call %.8x",(unsigned int)(buf[addr+1]|(buf[addr+2]<<8)|(buf[addr+3]<<16)|(buf[addr+4]<<24)));
|
return fmt::sprintf("call %.8x",(unsigned int)(buf[addr+1]|(buf[addr+2]<<8)|(buf[addr+3]<<16)|(buf[addr+4]<<24)));
|
||||||
break;
|
break;
|
||||||
case 0xf7:
|
case 0xf7:
|
||||||
return "CMD";
|
return "cmd";
|
||||||
break;
|
break;
|
||||||
case 0xf8:
|
case 0xf8:
|
||||||
if (addr+2>=bufLen) return "???";
|
if (addr+2>=bufLen) return "???";
|
||||||
|
@ -329,7 +335,7 @@ void FurnaceGUI::drawCSPlayer() {
|
||||||
csDisAsm.clear();
|
csDisAsm.clear();
|
||||||
unsigned char* buf=cs->getData();
|
unsigned char* buf=cs->getData();
|
||||||
for (size_t i=csDisAsmAddr; i<cs->getDataLen();) {
|
for (size_t i=csDisAsmAddr; i<cs->getDataLen();) {
|
||||||
int insLen=DivCS::getInsLength(buf[i]);
|
int insLen=DivCS::getInsLength(buf[i],(((i+1)<cs->getDataLen())?buf[i+1]:0),cs->getFastCmds());
|
||||||
if (insLen<1) {
|
if (insLen<1) {
|
||||||
logE("INS %x NOT IMPLEMENTED...",buf[i]);
|
logE("INS %x NOT IMPLEMENTED...",buf[i]);
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue