prepare for multiple chip support, part 2
This commit is contained in:
parent
254bf18036
commit
f47543ab98
|
@ -246,7 +246,7 @@ const int chanTypes[11][17]={
|
|||
};
|
||||
|
||||
const char* DivEngine::getChannelName(int chan) {
|
||||
switch (song.system) {
|
||||
switch (song.system[0]) {
|
||||
case DIV_SYSTEM_NULL: case DIV_SYSTEM_YMU759:
|
||||
return chanNames[0][chan];
|
||||
break;
|
||||
|
@ -285,7 +285,7 @@ const char* DivEngine::getChannelName(int chan) {
|
|||
}
|
||||
|
||||
const char* DivEngine::getChannelShortName(int chan) {
|
||||
switch (song.system) {
|
||||
switch (song.system[0]) {
|
||||
case DIV_SYSTEM_NULL: case DIV_SYSTEM_YMU759:
|
||||
return chanShortNames[0][chan];
|
||||
break;
|
||||
|
@ -324,7 +324,7 @@ const char* DivEngine::getChannelShortName(int chan) {
|
|||
}
|
||||
|
||||
int DivEngine::getChannelType(int chan) {
|
||||
switch (song.system) {
|
||||
switch (song.system[0]) {
|
||||
case DIV_SYSTEM_NULL: case DIV_SYSTEM_YMU759:
|
||||
return chanTypes[0][chan];
|
||||
break;
|
||||
|
@ -362,8 +362,9 @@ int DivEngine::getChannelType(int chan) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
// TODO: multi system support
|
||||
int DivEngine::getMaxVolume() {
|
||||
switch (song.system) {
|
||||
switch (song.system[0]) {
|
||||
case DIV_SYSTEM_PCE:
|
||||
return 31;
|
||||
default:
|
||||
|
@ -373,7 +374,7 @@ int DivEngine::getMaxVolume() {
|
|||
}
|
||||
|
||||
int DivEngine::getMaxDuty() {
|
||||
switch (song.system) {
|
||||
switch (song.system[0]) {
|
||||
case DIV_SYSTEM_YM2610: case DIV_SYSTEM_YM2610_EXT:
|
||||
return 31;
|
||||
case DIV_SYSTEM_C64_6581: case DIV_SYSTEM_C64_8580:
|
||||
|
@ -387,7 +388,7 @@ int DivEngine::getMaxDuty() {
|
|||
}
|
||||
|
||||
int DivEngine::getMaxWave() {
|
||||
switch (song.system) {
|
||||
switch (song.system[0]) {
|
||||
case DIV_SYSTEM_PCE: case DIV_SYSTEM_GB:
|
||||
return 63;
|
||||
case DIV_SYSTEM_YM2610: case DIV_SYSTEM_YM2610_EXT:
|
||||
|
@ -425,22 +426,23 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
|||
return false;
|
||||
}
|
||||
unsigned char sys=0;
|
||||
ds.systemLen=1;
|
||||
if (ds.version<0x09) {
|
||||
// V E R S I O N -> 3 <-
|
||||
// AWESOME
|
||||
ds.system=DIV_SYSTEM_YMU759;
|
||||
ds.system[0]=DIV_SYSTEM_YMU759;
|
||||
} else {
|
||||
sys=reader.readC();
|
||||
ds.system=systemFromFile(sys);
|
||||
ds.system[0]=systemFromFile(sys);
|
||||
}
|
||||
if (ds.system==DIV_SYSTEM_NULL) {
|
||||
if (ds.system[0]==DIV_SYSTEM_NULL) {
|
||||
logE("invalid system 0x%.2x!",sys);
|
||||
lastError="system not supported. running old version?";
|
||||
delete[] file;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ds.system==DIV_SYSTEM_YMU759 && ds.version<0x10) { // TODO
|
||||
if (ds.system[0]==DIV_SYSTEM_YMU759 && ds.version<0x10) { // TODO
|
||||
ds.vendor=reader.readString((unsigned char)reader.readC());
|
||||
ds.carrier=reader.readString((unsigned char)reader.readC());
|
||||
ds.category=reader.readString((unsigned char)reader.readC());
|
||||
|
@ -510,7 +512,7 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
|||
}
|
||||
|
||||
logI("reading pattern matrix (%d)...\n",ds.ordersLen);
|
||||
for (int i=0; i<getChannelCount(ds.system); i++) {
|
||||
for (int i=0; i<getChannelCount(ds.system[0]); i++) {
|
||||
for (int j=0; j<ds.ordersLen; j++) {
|
||||
ds.orders.ord[i][j]=reader.readC();
|
||||
}
|
||||
|
@ -536,7 +538,7 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
|||
}
|
||||
|
||||
if (ins->mode) { // FM
|
||||
if (!isFMSystem(ds.system)) {
|
||||
if (!isFMSystem(ds.system[0])) {
|
||||
logE("FM instrument in non-FM system. oopsie?\n");
|
||||
lastError="FM instrument in non-FM system";
|
||||
delete[] file;
|
||||
|
@ -554,7 +556,7 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
|||
if (ds.version<0x13) {
|
||||
reader.readC();
|
||||
ins->fm.ops=2+reader.readC()*2;
|
||||
if (ds.system!=DIV_SYSTEM_YMU759) ins->fm.ops=4;
|
||||
if (ds.system[0]!=DIV_SYSTEM_YMU759) ins->fm.ops=4;
|
||||
} else {
|
||||
ins->fm.ops=4;
|
||||
}
|
||||
|
@ -623,7 +625,7 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
|||
);
|
||||
}
|
||||
} else { // STD
|
||||
if (ds.system!=DIV_SYSTEM_GB || ds.version<0x12) {
|
||||
if (ds.system[0]!=DIV_SYSTEM_GB || ds.version<0x12) {
|
||||
ins->std.volMacroLen=reader.readC();
|
||||
for (int j=0; j<ins->std.volMacroLen; j++) {
|
||||
if (ds.version<0x0e) {
|
||||
|
@ -676,7 +678,7 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
|||
ins->std.waveMacroLoop=reader.readC();
|
||||
}
|
||||
|
||||
if (ds.system==DIV_SYSTEM_C64_6581 || ds.system==DIV_SYSTEM_C64_8580) {
|
||||
if (ds.system[0]==DIV_SYSTEM_C64_6581 || ds.system[0]==DIV_SYSTEM_C64_8580) {
|
||||
ins->c64.triOn=reader.readC();
|
||||
ins->c64.sawOn=reader.readC();
|
||||
ins->c64.pulseOn=reader.readC();
|
||||
|
@ -707,14 +709,14 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
|||
ins->c64.ch3off=reader.readC();
|
||||
}
|
||||
|
||||
if (ds.system==DIV_SYSTEM_GB && ds.version>0x11) {
|
||||
if (ds.system[0]==DIV_SYSTEM_GB && ds.version>0x11) {
|
||||
ins->gb.envVol=reader.readC();
|
||||
ins->gb.envDir=reader.readC();
|
||||
ins->gb.envLen=reader.readC();
|
||||
ins->gb.soundLen=reader.readC();
|
||||
|
||||
logD("GB data: vol %d dir %d len %d sl %d\n",ins->gb.envVol,ins->gb.envDir,ins->gb.envLen,ins->gb.soundLen);
|
||||
} else if (ds.system==DIV_SYSTEM_GB) {
|
||||
} else if (ds.system[0]==DIV_SYSTEM_GB) {
|
||||
// try to convert macro to envelope
|
||||
if (ins->std.volMacroLen>0) {
|
||||
ins->gb.envVol=ins->std.volMacro[0];
|
||||
|
@ -755,8 +757,8 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
|||
}
|
||||
}
|
||||
|
||||
logI("reading patterns (%d channels, %d orders)...\n",getChannelCount(ds.system),ds.ordersLen);
|
||||
for (int i=0; i<getChannelCount(ds.system); i++) {
|
||||
logI("reading patterns (%d channels, %d orders)...\n",getChannelCount(ds.system[0]),ds.ordersLen);
|
||||
for (int i=0; i<getChannelCount(ds.system[0]); i++) {
|
||||
DivChannelData& chan=ds.pat[i];
|
||||
if (ds.version<0x0a) {
|
||||
chan.effectRows=1;
|
||||
|
@ -777,15 +779,15 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
|||
pat->data[k][0]=reader.readS();
|
||||
// octave
|
||||
pat->data[k][1]=reader.readS();
|
||||
if (ds.system==DIV_SYSTEM_SMS && ds.version<0x0e && pat->data[k][1]>0) {
|
||||
if (ds.system[0]==DIV_SYSTEM_SMS && ds.version<0x0e && pat->data[k][1]>0) {
|
||||
// apparently it was up one octave before
|
||||
pat->data[k][1]--;
|
||||
} else if (ds.system==DIV_SYSTEM_GENESIS && ds.version<0x0e && pat->data[k][1]>0 && i>5) {
|
||||
} else if (ds.system[0]==DIV_SYSTEM_GENESIS && ds.version<0x0e && pat->data[k][1]>0 && i>5) {
|
||||
// ditto
|
||||
pat->data[k][1]--;
|
||||
}
|
||||
if (ds.version<0x12) {
|
||||
if (ds.system==DIV_SYSTEM_GB && i==3 && pat->data[k][1]>0) {
|
||||
if (ds.system[0]==DIV_SYSTEM_GB && i==3 && pat->data[k][1]>0) {
|
||||
// back then noise was 2 octaves lower
|
||||
pat->data[k][1]-=2;
|
||||
}
|
||||
|
@ -801,7 +803,7 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
|||
}
|
||||
}
|
||||
if (ds.version<0x12) {
|
||||
if (ds.system==DIV_SYSTEM_GB && i==2 && pat->data[k][3]>0) {
|
||||
if (ds.system[0]==DIV_SYSTEM_GB && i==2 && pat->data[k][3]>0) {
|
||||
// volume range of GB wave channel was 0-3 rather than 0-F
|
||||
pat->data[k][3]=(pat->data[k][3]&3)*5;
|
||||
}
|
||||
|
@ -880,7 +882,7 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
|||
isBusy.lock();
|
||||
song.unload();
|
||||
song=ds;
|
||||
chans=getChannelCount(song.system);
|
||||
chans=getChannelCount(song.system[0]);
|
||||
renderSamples();
|
||||
isBusy.unlock();
|
||||
if (active) {
|
||||
|
@ -1021,8 +1023,14 @@ bool DivEngine::load(unsigned char* f, size_t slen) {
|
|||
}
|
||||
|
||||
SafeWriter* DivEngine::saveDMF() {
|
||||
// fail if more than one system
|
||||
if (song.systemLen!=1) {
|
||||
logE("cannot save multiple systems in this format!\n");
|
||||
lastError="multiple systems not possible on .dmf";
|
||||
return NULL;
|
||||
}
|
||||
// fail if this is an YMU759 song
|
||||
if (song.system==DIV_SYSTEM_YMU759) {
|
||||
if (song.system[0]==DIV_SYSTEM_YMU759) {
|
||||
logE("cannot save YMU759 song!\n");
|
||||
lastError="YMU759 song saving is not supported";
|
||||
return NULL;
|
||||
|
@ -1034,7 +1042,7 @@ SafeWriter* DivEngine::saveDMF() {
|
|||
w->write(DIV_DMF_MAGIC,16);
|
||||
// version
|
||||
w->writeC(24);
|
||||
w->writeC(systemToFile(song.system));
|
||||
w->writeC(systemToFile(song.system[0]));
|
||||
|
||||
// song info
|
||||
w->writeString(song.name,true);
|
||||
|
@ -1054,7 +1062,7 @@ SafeWriter* DivEngine::saveDMF() {
|
|||
w->writeI(song.patLen);
|
||||
w->writeC(song.ordersLen);
|
||||
|
||||
for (int i=0; i<getChannelCount(song.system); i++) {
|
||||
for (int i=0; i<chans; i++) {
|
||||
for (int j=0; j<song.ordersLen; j++) {
|
||||
w->writeC(song.orders.ord[i][j]);
|
||||
}
|
||||
|
@ -1086,7 +1094,7 @@ SafeWriter* DivEngine::saveDMF() {
|
|||
w->writeC(op.ssgEnv);
|
||||
}
|
||||
} else { // STD
|
||||
if (song.system!=DIV_SYSTEM_GB) {
|
||||
if (song.system[0]!=DIV_SYSTEM_GB) {
|
||||
w->writeC(i->std.volMacroLen);
|
||||
w->write(i->std.volMacro,4*i->std.volMacroLen);
|
||||
if (i->std.volMacroLen>0) {
|
||||
|
@ -1113,7 +1121,7 @@ SafeWriter* DivEngine::saveDMF() {
|
|||
w->writeC(i->std.waveMacroLoop);
|
||||
}
|
||||
|
||||
if (song.system==DIV_SYSTEM_C64_6581 || song.system==DIV_SYSTEM_C64_8580) {
|
||||
if (song.system[0]==DIV_SYSTEM_C64_6581 || song.system[0]==DIV_SYSTEM_C64_8580) {
|
||||
w->writeC(i->c64.triOn);
|
||||
w->writeC(i->c64.sawOn);
|
||||
w->writeC(i->c64.pulseOn);
|
||||
|
@ -1141,7 +1149,7 @@ SafeWriter* DivEngine::saveDMF() {
|
|||
w->writeC(i->c64.ch3off);
|
||||
}
|
||||
|
||||
if (song.system==DIV_SYSTEM_GB) {
|
||||
if (song.system[0]==DIV_SYSTEM_GB) {
|
||||
w->writeC(i->gb.envVol);
|
||||
w->writeC(i->gb.envDir);
|
||||
w->writeC(i->gb.envLen);
|
||||
|
@ -1156,7 +1164,7 @@ SafeWriter* DivEngine::saveDMF() {
|
|||
w->write(i->data,4*i->len);
|
||||
}
|
||||
|
||||
for (int i=0; i<getChannelCount(song.system); i++) {
|
||||
for (int i=0; i<getChannelCount(song.system[0]); i++) {
|
||||
w->writeC(song.pat[i].effectRows);
|
||||
|
||||
for (int j=0; j<song.ordersLen; j++) {
|
||||
|
@ -1464,31 +1472,29 @@ void DivEngine::renderSamples() {
|
|||
}
|
||||
}
|
||||
|
||||
// step 3: allocate the samples if needed
|
||||
if (song.system==DIV_SYSTEM_YM2610 || song.system==DIV_SYSTEM_YM2610_EXT) {
|
||||
if (adpcmMem==NULL) adpcmMem=new unsigned char[16777216];
|
||||
// step 3: allocate ADPCM samples
|
||||
if (adpcmMem==NULL) adpcmMem=new unsigned char[16777216];
|
||||
|
||||
size_t memPos=0;
|
||||
for (int i=0; i<song.sampleLen; i++) {
|
||||
DivSample* s=song.sample[i];
|
||||
if ((memPos&0xf00000)!=((memPos+s->adpcmRendLength)&0xf00000)) {
|
||||
memPos=(memPos+0xfffff)&0xf00000;
|
||||
}
|
||||
memcpy(adpcmMem+memPos,s->adpcmRendData,s->adpcmRendLength);
|
||||
s->rendOff=memPos;
|
||||
memPos+=s->adpcmRendLength;
|
||||
size_t memPos=0;
|
||||
for (int i=0; i<song.sampleLen; i++) {
|
||||
DivSample* s=song.sample[i];
|
||||
if ((memPos&0xf00000)!=((memPos+s->adpcmRendLength)&0xf00000)) {
|
||||
memPos=(memPos+0xfffff)&0xf00000;
|
||||
}
|
||||
memcpy(adpcmMem+memPos,s->adpcmRendData,s->adpcmRendLength);
|
||||
s->rendOff=memPos;
|
||||
memPos+=s->adpcmRendLength;
|
||||
}
|
||||
}
|
||||
|
||||
void DivEngine::createNew() {
|
||||
DivSystem sys=song.system;
|
||||
DivSystem sys=song.system[0];
|
||||
quitDispatch();
|
||||
isBusy.lock();
|
||||
song.unload();
|
||||
song=DivSong();
|
||||
song.system=sys;
|
||||
chans=getChannelCount(song.system);
|
||||
song.system[0]=sys;
|
||||
chans=getChannelCount(song.system[0]);
|
||||
renderSamples();
|
||||
isBusy.unlock();
|
||||
initDispatch();
|
||||
|
@ -1500,14 +1506,14 @@ void DivEngine::createNew() {
|
|||
void DivEngine::changeSystem(DivSystem which) {
|
||||
quitDispatch();
|
||||
isBusy.lock();
|
||||
song.system=which;
|
||||
chans=getChannelCount(song.system);
|
||||
song.system[0]=which;
|
||||
chans=getChannelCount(song.system[0]);
|
||||
// instrument safety check
|
||||
for (DivInstrument* i: song.ins) {
|
||||
if (!isFMSystem(song.system) && i->mode) {
|
||||
if (!isFMSystem(song.system[0]) && i->mode) {
|
||||
i->mode=false;
|
||||
}
|
||||
if (!isSTDSystem(song.system) && !i->mode) {
|
||||
if (!isSTDSystem(song.system[0]) && !i->mode) {
|
||||
i->mode=true;
|
||||
}
|
||||
}
|
||||
|
@ -1659,7 +1665,7 @@ int DivEngine::divToFileRate(int drate) {
|
|||
|
||||
int DivEngine::getEffectiveSampleRate(int rate) {
|
||||
if (rate<1) return 0;
|
||||
switch (song.system) {
|
||||
switch (song.system[0]) {
|
||||
case DIV_SYSTEM_YMU759:
|
||||
return 8000;
|
||||
case DIV_SYSTEM_GENESIS: case DIV_SYSTEM_GENESIS_EXT:
|
||||
|
@ -1807,7 +1813,7 @@ int DivEngine::addInstrument() {
|
|||
DivInstrument* ins=new DivInstrument;
|
||||
int insCount=(int)song.ins.size();
|
||||
ins->name=fmt::sprintf("Instrument %d",insCount);
|
||||
ins->mode=isFMSystem(song.system);
|
||||
ins->mode=isFMSystem(song.system[0]);
|
||||
song.ins.push_back(ins);
|
||||
song.insLen=insCount+1;
|
||||
isBusy.unlock();
|
||||
|
@ -2085,7 +2091,7 @@ void DivEngine::setConsoleMode(bool enable) {
|
|||
void DivEngine::initDispatch() {
|
||||
if (dispatch!=NULL) return;
|
||||
isBusy.lock();
|
||||
switch (song.system) {
|
||||
switch (song.system[0]) {
|
||||
case DIV_SYSTEM_GENESIS:
|
||||
dispatch=new DivPlatformGenesis;
|
||||
break;
|
||||
|
@ -2127,8 +2133,8 @@ void DivEngine::initDispatch() {
|
|||
dispatch=new DivPlatformDummy;
|
||||
break;
|
||||
}
|
||||
dispatch->init(this,getChannelCount(song.system),got.rate,(!song.pal) || (song.customTempo!=0 && song.hz<53));
|
||||
chans=getChannelCount(song.system);
|
||||
dispatch->init(this,getChannelCount(song.system[0]),got.rate,(!song.pal) || (song.customTempo!=0 && song.hz<53));
|
||||
chans=getChannelCount(song.system[0]);
|
||||
|
||||
blip_set_rates(bb[0],dispatch->rate,got.rate);
|
||||
blip_set_rates(bb[1],dispatch->rate,got.rate);
|
||||
|
|
|
@ -94,7 +94,7 @@ int DivEngine::dispatchCmd(DivCommand c) {
|
|||
}
|
||||
|
||||
bool DivEngine::perSystemEffect(int ch, unsigned char effect, unsigned char effectVal) {
|
||||
switch (song.system) {
|
||||
switch (song.system[0]) {
|
||||
case DIV_SYSTEM_GENESIS:
|
||||
case DIV_SYSTEM_GENESIS_EXT:
|
||||
switch (effect) {
|
||||
|
@ -172,7 +172,7 @@ bool DivEngine::perSystemEffect(int ch, unsigned char effect, unsigned char effe
|
|||
}
|
||||
|
||||
bool DivEngine::perSystemPostEffect(int ch, unsigned char effect, unsigned char effectVal) {
|
||||
switch (song.system) {
|
||||
switch (song.system[0]) {
|
||||
case DIV_SYSTEM_GENESIS:
|
||||
case DIV_SYSTEM_GENESIS_EXT:
|
||||
case DIV_SYSTEM_ARCADE:
|
||||
|
@ -180,7 +180,7 @@ bool DivEngine::perSystemPostEffect(int ch, unsigned char effect, unsigned char
|
|||
case DIV_SYSTEM_YM2610_EXT:
|
||||
switch (effect) {
|
||||
case 0x10: // LFO or noise mode
|
||||
if (song.system==DIV_SYSTEM_ARCADE) {
|
||||
if (song.system[0]==DIV_SYSTEM_ARCADE) {
|
||||
dispatchCmd(DivCommand(DIV_CMD_STD_NOISE_FREQ,ch,effectVal));
|
||||
} else {
|
||||
dispatchCmd(DivCommand(DIV_CMD_FM_LFO,ch,effectVal));
|
||||
|
@ -207,12 +207,12 @@ bool DivEngine::perSystemPostEffect(int ch, unsigned char effect, unsigned char
|
|||
}
|
||||
break;
|
||||
case 0x17: // arcade LFO
|
||||
if (song.system==DIV_SYSTEM_ARCADE) {
|
||||
if (song.system[0]==DIV_SYSTEM_ARCADE) {
|
||||
dispatchCmd(DivCommand(DIV_CMD_FM_LFO,ch,effectVal));
|
||||
}
|
||||
break;
|
||||
case 0x18: // EXT or LFO waveform
|
||||
if (song.system==DIV_SYSTEM_ARCADE) {
|
||||
if (song.system[0]==DIV_SYSTEM_ARCADE) {
|
||||
dispatchCmd(DivCommand(DIV_CMD_FM_LFO_WAVE,ch,effectVal));
|
||||
} else {
|
||||
dispatchCmd(DivCommand(DIV_CMD_FM_EXTCH,ch,effectVal));
|
||||
|
@ -234,29 +234,29 @@ bool DivEngine::perSystemPostEffect(int ch, unsigned char effect, unsigned char
|
|||
dispatchCmd(DivCommand(DIV_CMD_FM_AR,ch,3,effectVal&31));
|
||||
break;
|
||||
case 0x20: // PCM frequency or Neo Geo PSG mode
|
||||
if (song.system==DIV_SYSTEM_ARCADE) {
|
||||
if (song.system[0]==DIV_SYSTEM_ARCADE) {
|
||||
dispatchCmd(DivCommand(DIV_CMD_SAMPLE_FREQ,ch,effectVal));
|
||||
} else if (song.system==DIV_SYSTEM_YM2610 || song.system==DIV_SYSTEM_YM2610_EXT) {
|
||||
} else if (song.system[0]==DIV_SYSTEM_YM2610 || song.system[0]==DIV_SYSTEM_YM2610_EXT) {
|
||||
dispatchCmd(DivCommand(DIV_CMD_STD_NOISE_MODE,ch,effectVal));
|
||||
}
|
||||
break;
|
||||
case 0x21: // Neo Geo PSG noise freq
|
||||
if (song.system==DIV_SYSTEM_YM2610 || song.system==DIV_SYSTEM_YM2610_EXT) {
|
||||
if (song.system[0]==DIV_SYSTEM_YM2610 || song.system[0]==DIV_SYSTEM_YM2610_EXT) {
|
||||
dispatchCmd(DivCommand(DIV_CMD_STD_NOISE_FREQ,ch,effectVal));
|
||||
}
|
||||
break;
|
||||
case 0x22: // UNOFFICIAL: Neo Geo PSG envelope enable
|
||||
if (song.system==DIV_SYSTEM_YM2610 || song.system==DIV_SYSTEM_YM2610_EXT) {
|
||||
if (song.system[0]==DIV_SYSTEM_YM2610 || song.system[0]==DIV_SYSTEM_YM2610_EXT) {
|
||||
dispatchCmd(DivCommand(DIV_CMD_AY_ENVELOPE_SET,ch,effectVal));
|
||||
}
|
||||
break;
|
||||
case 0x23: // UNOFFICIAL: Neo Geo PSG envelope period low
|
||||
if (song.system==DIV_SYSTEM_YM2610 || song.system==DIV_SYSTEM_YM2610_EXT) {
|
||||
if (song.system[0]==DIV_SYSTEM_YM2610 || song.system[0]==DIV_SYSTEM_YM2610_EXT) {
|
||||
dispatchCmd(DivCommand(DIV_CMD_AY_ENVELOPE_LOW,ch,effectVal));
|
||||
}
|
||||
break;
|
||||
case 0x24: // UNOFFICIAL: Neo Geo PSG envelope period high
|
||||
if (song.system==DIV_SYSTEM_YM2610 || song.system==DIV_SYSTEM_YM2610_EXT) {
|
||||
if (song.system[0]==DIV_SYSTEM_YM2610 || song.system[0]==DIV_SYSTEM_YM2610_EXT) {
|
||||
dispatchCmd(DivCommand(DIV_CMD_AY_ENVELOPE_HIGH,ch,effectVal));
|
||||
}
|
||||
break;
|
||||
|
@ -322,7 +322,7 @@ void DivEngine::processRow(int i, bool afterDelay) {
|
|||
chan[i].delayOrder=whatOrder;
|
||||
chan[i].delayRow=whatRow;
|
||||
if (effectVal==nextSpeed) {
|
||||
if (song.system!=DIV_SYSTEM_YM2610 && song.system!=DIV_SYSTEM_YM2610_EXT) chan[i].delayLocked=true;
|
||||
if (song.system[0]!=DIV_SYSTEM_YM2610 && song.system[0]!=DIV_SYSTEM_YM2610_EXT) chan[i].delayLocked=true;
|
||||
} else {
|
||||
chan[i].delayLocked=false;
|
||||
}
|
||||
|
@ -351,7 +351,7 @@ void DivEngine::processRow(int i, bool afterDelay) {
|
|||
if (dispatch->keyOffAffectsPorta(i)) {
|
||||
chan[i].portaNote=-1;
|
||||
chan[i].portaSpeed=-1;
|
||||
if (i==2 && song.system==DIV_SYSTEM_SMS) {
|
||||
if (i==2 && song.system[0]==DIV_SYSTEM_SMS) {
|
||||
chan[i+1].portaNote=-1;
|
||||
chan[i+1].portaSpeed=-1;
|
||||
}
|
||||
|
@ -507,7 +507,7 @@ void DivEngine::processRow(int i, bool afterDelay) {
|
|||
break;
|
||||
case 0xe5: // pitch
|
||||
chan[i].pitch=effectVal-0x80;
|
||||
if (song.system==DIV_SYSTEM_ARCADE) { // arcade pitch oddity
|
||||
if (song.system[0]==DIV_SYSTEM_ARCADE) { // arcade pitch oddity
|
||||
chan[i].pitch*=2;
|
||||
if (chan[i].pitch<-128) chan[i].pitch=-128;
|
||||
if (chan[i].pitch>127) chan[i].pitch=127;
|
||||
|
@ -642,7 +642,7 @@ void DivEngine::nextRow() {
|
|||
}
|
||||
}
|
||||
|
||||
if (song.system==DIV_SYSTEM_YMU759) {
|
||||
if (song.system[0]==DIV_SYSTEM_YMU759) {
|
||||
if (speedAB) {
|
||||
ticks=speed2;
|
||||
nextSpeed=speed1;
|
||||
|
@ -678,7 +678,7 @@ bool DivEngine::nextTick(bool noAccum) {
|
|||
if (song.customTempo) {
|
||||
divider=song.hz;
|
||||
} else {
|
||||
if (song.system==DIV_SYSTEM_YMU759) {
|
||||
if (song.system[0]==DIV_SYSTEM_YMU759) {
|
||||
switch (song.timeBase) {
|
||||
case 0:
|
||||
divider=248;
|
||||
|
|
|
@ -78,7 +78,8 @@ struct DivSong {
|
|||
|
||||
// system
|
||||
// TODO: multi-chip support
|
||||
DivSystem system;
|
||||
DivSystem system[32];
|
||||
unsigned char systemLen;
|
||||
|
||||
// song information
|
||||
String name, author;
|
||||
|
@ -108,7 +109,7 @@ struct DivSong {
|
|||
|
||||
DivSong():
|
||||
version(24),
|
||||
system(DIV_SYSTEM_GENESIS),
|
||||
systemLen(1),
|
||||
name(""),
|
||||
author(""),
|
||||
carrier(""),
|
||||
|
@ -136,5 +137,9 @@ struct DivSong {
|
|||
insLen(0),
|
||||
waveLen(0),
|
||||
sampleLen(0) {
|
||||
for (int i=0; i<32; i++) {
|
||||
system[i]=DIV_SYSTEM_NULL;
|
||||
}
|
||||
system[0]=DIV_SYSTEM_GENESIS;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -156,10 +156,12 @@ void FurnaceGUI::addScroll(int amount) {
|
|||
}
|
||||
|
||||
void FurnaceGUI::updateWindowTitle() {
|
||||
String type=e->getSystemName(e->song.system[0]);
|
||||
if (e->song.systemLen>1) type="multi-system";
|
||||
if (e->song.name.empty()) {
|
||||
SDL_SetWindowTitle(sdlWin,fmt::sprintf("Furnace (%s)",e->getSystemName(e->song.system)).c_str());
|
||||
SDL_SetWindowTitle(sdlWin,fmt::sprintf("Furnace (%s)",type).c_str());
|
||||
} else {
|
||||
SDL_SetWindowTitle(sdlWin,fmt::sprintf("%s - Furnace (%s)",e->song.name,e->getSystemName(e->song.system)).c_str());
|
||||
SDL_SetWindowTitle(sdlWin,fmt::sprintf("%s - Furnace (%s)",e->song.name,type).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -562,7 +564,7 @@ void FurnaceGUI::drawInsEdit() {
|
|||
} else {
|
||||
DivInstrument* ins=e->song.ins[curIns];
|
||||
ImGui::InputText("Name",&ins->name);
|
||||
if (e->isFMSystem(e->song.system) && e->isSTDSystem(e->song.system)) ImGui::Checkbox("FM",&ins->mode);
|
||||
if (e->isFMSystem(e->song.system[0]) && e->isSTDSystem(e->song.system[0])) ImGui::Checkbox("FM",&ins->mode);
|
||||
|
||||
if (ins->mode) { // FM
|
||||
ImGui::Columns(3,NULL,false);
|
||||
|
@ -597,7 +599,7 @@ void FurnaceGUI::drawInsEdit() {
|
|||
if (ImGui::SliderInt("Detune",&detune,-3,3)) {
|
||||
op.dt=detune&7;
|
||||
}
|
||||
if (e->song.system==DIV_SYSTEM_ARCADE) {
|
||||
if (e->song.system[0]==DIV_SYSTEM_ARCADE) {
|
||||
ImGui::SliderScalar("Detune 2",ImGuiDataType_U8,&op.dt2,&_ZERO,&_THREE);
|
||||
} else {
|
||||
bool ssgOn=op.ssgEnv&8;
|
||||
|
@ -622,7 +624,7 @@ void FurnaceGUI::drawInsEdit() {
|
|||
float loopIndicator[128];
|
||||
|
||||
// GB specifics
|
||||
if (e->song.system==DIV_SYSTEM_GB) {
|
||||
if (e->song.system[0]==DIV_SYSTEM_GB) {
|
||||
ImGui::SliderScalar("Volume",ImGuiDataType_U8,&ins->gb.envVol,&_ZERO,&_FIFTEEN);
|
||||
ImGui::SliderScalar("Envelope Length",ImGuiDataType_U8,&ins->gb.envLen,&_ZERO,&_SEVEN);
|
||||
ImGui::SliderScalar("Sound Length",ImGuiDataType_U8,&ins->gb.soundLen,&_ZERO,&_SIXTY_FOUR,ins->gb.soundLen>63?"Infinity":"%d");
|
||||
|
@ -633,7 +635,7 @@ void FurnaceGUI::drawInsEdit() {
|
|||
}
|
||||
|
||||
// C64 specifics
|
||||
if (e->song.system==DIV_SYSTEM_C64_6581 || e->song.system==DIV_SYSTEM_C64_8580) {
|
||||
if (e->song.system[0]==DIV_SYSTEM_C64_6581 || e->song.system[0]==DIV_SYSTEM_C64_8580) {
|
||||
ImGui::Text("Waveform");
|
||||
ImGui::SameLine();
|
||||
ImGui::PushStyleColor(ImGuiCol_Button,ImVec4(0.2f,(ins->c64.triOn)?0.6f:0.2f,0.2f,1.0f));
|
||||
|
@ -707,15 +709,15 @@ void FurnaceGUI::drawInsEdit() {
|
|||
}
|
||||
|
||||
// volume macro
|
||||
if (e->song.system!=DIV_SYSTEM_GB) {
|
||||
if (e->song.system[0]!=DIV_SYSTEM_GB) {
|
||||
ImGui::Separator();
|
||||
if ((e->song.system==DIV_SYSTEM_C64_6581 || e->song.system==DIV_SYSTEM_C64_8580) && ins->c64.volIsCutoff) {
|
||||
if ((e->song.system[0]==DIV_SYSTEM_C64_6581 || e->song.system[0]==DIV_SYSTEM_C64_8580) && ins->c64.volIsCutoff) {
|
||||
ImGui::Text("Relative Cutoff Macro");
|
||||
} else {
|
||||
ImGui::Text("Volume Macro");
|
||||
}
|
||||
for (int i=0; i<ins->std.volMacroLen; i++) {
|
||||
if ((e->song.system==DIV_SYSTEM_C64_6581 || e->song.system==DIV_SYSTEM_C64_8580) && ins->c64.volIsCutoff) {
|
||||
if ((e->song.system[0]==DIV_SYSTEM_C64_6581 || e->song.system[0]==DIV_SYSTEM_C64_8580) && ins->c64.volIsCutoff) {
|
||||
asFloat[i]=ins->std.volMacro[i]-18;
|
||||
} else {
|
||||
asFloat[i]=ins->std.volMacro[i];
|
||||
|
@ -724,7 +726,7 @@ void FurnaceGUI::drawInsEdit() {
|
|||
}
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding,ImVec2(0.0f,0.0f));
|
||||
int volMax=e->getMaxVolume();
|
||||
if (e->song.system==DIV_SYSTEM_C64_6581 || e->song.system==DIV_SYSTEM_C64_8580) {
|
||||
if (e->song.system[0]==DIV_SYSTEM_C64_6581 || e->song.system[0]==DIV_SYSTEM_C64_8580) {
|
||||
if (ins->c64.volIsCutoff) volMax=36;
|
||||
}
|
||||
ImGui::PlotHistogram("##IVolMacro",asFloat,ins->std.volMacroLen,0,NULL,0,volMax,ImVec2(400.0f*dpiScale,200.0f*dpiScale));
|
||||
|
@ -799,9 +801,9 @@ void FurnaceGUI::drawInsEdit() {
|
|||
int dutyMax=e->getMaxDuty();
|
||||
if (dutyMax>0) {
|
||||
ImGui::Separator();
|
||||
if (e->song.system==DIV_SYSTEM_C64_6581 || e->song.system==DIV_SYSTEM_C64_8580) {
|
||||
if (e->song.system[0]==DIV_SYSTEM_C64_6581 || e->song.system[0]==DIV_SYSTEM_C64_8580) {
|
||||
ImGui::Text("Relative Duty Macro");
|
||||
} else if (e->song.system==DIV_SYSTEM_YM2610 || e->song.system==DIV_SYSTEM_YM2610_EXT) {
|
||||
} else if (e->song.system[0]==DIV_SYSTEM_YM2610 || e->song.system[0]==DIV_SYSTEM_YM2610_EXT) {
|
||||
ImGui::Text("Noise Frequency Macro");
|
||||
} else {
|
||||
ImGui::Text("Duty/Noise Mode Macro");
|
||||
|
@ -921,7 +923,7 @@ void FurnaceGUI::drawWaveList() {
|
|||
}
|
||||
}
|
||||
ImGui::SameLine();
|
||||
PlotNoLerp(fmt::sprintf("##_WAVEP%d",i).c_str(),wavePreview,wave->len+1,0,NULL,0,e->getWaveRes(e->song.system));
|
||||
PlotNoLerp(fmt::sprintf("##_WAVEP%d",i).c_str(),wavePreview,wave->len+1,0,NULL,0,e->getWaveRes(e->song.system[0]));
|
||||
}
|
||||
}
|
||||
if (ImGui::IsWindowFocused()) curWindow=GUI_WINDOW_WAVE_LIST;
|
||||
|
@ -942,12 +944,12 @@ void FurnaceGUI::drawWaveEdit() {
|
|||
if (wave->len>0) wavePreview[wave->len]=wave->data[wave->len-1];
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding,ImVec2(0.0f,0.0f));
|
||||
ImVec2 contentRegion=ImGui::GetContentRegionAvail();
|
||||
PlotNoLerp("##Waveform",wavePreview,wave->len+1,0,NULL,0,e->getWaveRes(e->song.system),contentRegion);
|
||||
PlotNoLerp("##Waveform",wavePreview,wave->len+1,0,NULL,0,e->getWaveRes(e->song.system[0]),contentRegion);
|
||||
if (ImGui::IsItemClicked(ImGuiMouseButton_Left)) {
|
||||
waveDragStart=ImGui::GetItemRectMin();
|
||||
waveDragAreaSize=contentRegion;
|
||||
waveDragMin=0;
|
||||
waveDragMax=e->getWaveRes(e->song.system);
|
||||
waveDragMax=e->getWaveRes(e->song.system[0]);
|
||||
waveDragLen=wave->len;
|
||||
waveDragActive=true;
|
||||
waveDragTarget=wave->data;
|
||||
|
@ -1712,7 +1714,7 @@ void FurnaceGUI::prepareUndo(ActionType action) {
|
|||
int order=e->getOrder();
|
||||
switch (action) {
|
||||
case GUI_ACTION_CHANGE_SYSTEM:
|
||||
oldSystem=e->song.system;
|
||||
oldSystem=e->song.system[0];
|
||||
break;
|
||||
case GUI_ACTION_CHANGE_ORDER:
|
||||
oldOrders=e->song.orders;
|
||||
|
@ -1743,9 +1745,9 @@ void FurnaceGUI::makeUndo(ActionType action) {
|
|||
s.nibble=curNibble;
|
||||
switch (action) {
|
||||
case GUI_ACTION_CHANGE_SYSTEM:
|
||||
if (oldSystem!=e->song.system) {
|
||||
if (oldSystem!=e->song.system[0]) {
|
||||
s.oldSystem=oldSystem;
|
||||
s.newSystem=e->song.system;
|
||||
s.newSystem=e->song.system[0];
|
||||
doPush=true;
|
||||
}
|
||||
break;
|
||||
|
@ -2572,7 +2574,7 @@ void FurnaceGUI::processDrags(int dragX, int dragY) {
|
|||
}
|
||||
|
||||
#define sysChangeOption(x) \
|
||||
if (ImGui::MenuItem(e->getSystemName(x),NULL,e->song.system==x)) { \
|
||||
if (ImGui::MenuItem(e->getSystemName(x),NULL,e->song.system[0]==x)) { \
|
||||
prepareUndo(GUI_ACTION_CHANGE_SYSTEM); \
|
||||
e->changeSystem(x); \
|
||||
updateWindowTitle(); \
|
||||
|
|
Loading…
Reference in New Issue