new floating-point volumes and patchbay
This commit is contained in:
parent
7f5cdd6f6b
commit
6273275b47
|
@ -32,6 +32,8 @@ these fields are 0 in format versions prior to 100 (0.6pre1).
|
||||||
|
|
||||||
the format versions are:
|
the format versions are:
|
||||||
|
|
||||||
|
- 135: Furnace dev135
|
||||||
|
- 134: Furnace dev134
|
||||||
- 133: Furnace 0.6pre3
|
- 133: Furnace 0.6pre3
|
||||||
- 132: Furnace 0.6pre2
|
- 132: Furnace 0.6pre2
|
||||||
- 131: Furnace dev131
|
- 131: Furnace dev131
|
||||||
|
@ -386,8 +388,38 @@ size | description
|
||||||
STR | song author (Japanese)
|
STR | song author (Japanese)
|
||||||
STR | system name (Japanese)
|
STR | system name (Japanese)
|
||||||
STR | album/category/game name (Japanese)
|
STR | album/category/game name (Japanese)
|
||||||
|
--- | **extra chip output settings (× chipCount)** (>=135)
|
||||||
|
4f | chip volume
|
||||||
|
4f | chip panning
|
||||||
|
4f | chip front/rear balance
|
||||||
|
--- | **patchbay** (>=135)
|
||||||
|
4 | patchbay connection count
|
||||||
|
4?? | patchbay
|
||||||
|
| - see next section for more details.
|
||||||
```
|
```
|
||||||
|
|
||||||
|
# patchbay
|
||||||
|
|
||||||
|
Furnace dev135 adds a "patchbay" which allows for arbitrary connection of chip outputs to system outputs.
|
||||||
|
it eventually will allow connecting outputs to effects and so on.
|
||||||
|
|
||||||
|
a connection is represented as an unsigned int in the following format:
|
||||||
|
|
||||||
|
- bit 16-31: source port
|
||||||
|
- bit 0-15: destination port
|
||||||
|
|
||||||
|
a port is in the following format (hexadecimal): `xxxy`
|
||||||
|
|
||||||
|
- `xxx` (bit 4 to 15) represents an entity.
|
||||||
|
- `y` (bit 0 to 3) is the port of that entity.
|
||||||
|
|
||||||
|
reserved input entities:
|
||||||
|
- `000`: system outputs
|
||||||
|
- `FFF`: "null" entity
|
||||||
|
|
||||||
|
reserved output entities:
|
||||||
|
- `000` through `01F`: chip outputs
|
||||||
|
|
||||||
# subsong
|
# subsong
|
||||||
|
|
||||||
from version 95 onwards, Furnace supports storing multiple songs on a single file.
|
from version 95 onwards, Furnace supports storing multiple songs on a single file.
|
||||||
|
|
|
@ -1341,8 +1341,8 @@ String DivEngine::decodeSysDesc(String desc) {
|
||||||
int val=0;
|
int val=0;
|
||||||
int curStage=0;
|
int curStage=0;
|
||||||
int sysID=0;
|
int sysID=0;
|
||||||
int sysVol=0;
|
float sysVol=0;
|
||||||
int sysPan=0;
|
float sysPan=0;
|
||||||
int sysFlags=0;
|
int sysFlags=0;
|
||||||
int curSys=0;
|
int curSys=0;
|
||||||
desc+=' '; // ha
|
desc+=' '; // ha
|
||||||
|
@ -1357,24 +1357,25 @@ String DivEngine::decodeSysDesc(String desc) {
|
||||||
curStage++;
|
curStage++;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
sysVol=val;
|
sysVol=(float)val/64.0f;
|
||||||
curStage++;
|
curStage++;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
sysPan=val;
|
sysPan=(float)val/127.0f;
|
||||||
curStage++;
|
curStage++;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
sysFlags=val;
|
sysFlags=val;
|
||||||
|
|
||||||
if (sysID!=0) {
|
if (sysID!=0) {
|
||||||
if (sysVol<-128) sysVol=-128;
|
if (sysVol<-1.0f) sysVol=-1.0f;
|
||||||
if (sysVol>127) sysVol=127;
|
if (sysVol>1.0f) sysVol=1.0f;
|
||||||
if (sysPan<-128) sysPan=-128;
|
if (sysPan<-1.0f) sysPan=-1.0f;
|
||||||
if (sysPan>127) sysPan=127;
|
if (sysPan>1.0f) sysPan=1.0f;
|
||||||
newDesc.set(fmt::sprintf("id%d",curSys),sysID);
|
newDesc.set(fmt::sprintf("id%d",curSys),sysID);
|
||||||
newDesc.set(fmt::sprintf("vol%d",curSys),sysVol);
|
newDesc.set(fmt::sprintf("vol%d",curSys),sysVol);
|
||||||
newDesc.set(fmt::sprintf("pan%d",curSys),sysPan);
|
newDesc.set(fmt::sprintf("pan%d",curSys),sysPan);
|
||||||
|
newDesc.set(fmt::sprintf("fr%d",curSys),0.0f);
|
||||||
DivConfig newFlagsC;
|
DivConfig newFlagsC;
|
||||||
newFlagsC.clear();
|
newFlagsC.clear();
|
||||||
convertOldFlags((unsigned int)sysFlags,newFlagsC,systemFromFileFur(sysID));
|
convertOldFlags((unsigned int)sysFlags,newFlagsC,systemFromFileFur(sysID));
|
||||||
|
@ -1404,7 +1405,7 @@ String DivEngine::decodeSysDesc(String desc) {
|
||||||
return newDesc.toBase64();
|
return newDesc.toBase64();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DivEngine::initSongWithDesc(const char* description, bool inBase64) {
|
void DivEngine::initSongWithDesc(const char* description, bool inBase64, bool oldVol) {
|
||||||
int chanCount=0;
|
int chanCount=0;
|
||||||
DivConfig c;
|
DivConfig c;
|
||||||
if (inBase64) {
|
if (inBase64) {
|
||||||
|
@ -1423,9 +1424,16 @@ void DivEngine::initSongWithDesc(const char* description, bool inBase64) {
|
||||||
song.system[index]=DIV_SYSTEM_NULL;
|
song.system[index]=DIV_SYSTEM_NULL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
song.systemVol[index]=c.getInt(fmt::sprintf("vol%d",index),DIV_SYSTEM_NULL);
|
song.systemVol[index]=c.getFloat(fmt::sprintf("vol%d",index),1.0f);
|
||||||
song.systemPan[index]=c.getInt(fmt::sprintf("pan%d",index),DIV_SYSTEM_NULL);
|
song.systemPan[index]=c.getFloat(fmt::sprintf("pan%d",index),0.0f);
|
||||||
|
song.systemPanFR[index]=c.getFloat(fmt::sprintf("fr%d",index),0.0f);
|
||||||
song.systemFlags[index].clear();
|
song.systemFlags[index].clear();
|
||||||
|
|
||||||
|
if (oldVol) {
|
||||||
|
song.systemVol[index]/=64.0f;
|
||||||
|
song.systemPan[index]/=127.0f;
|
||||||
|
}
|
||||||
|
|
||||||
String flags=c.getString(fmt::sprintf("flags%d",index),"");
|
String flags=c.getString(fmt::sprintf("flags%d",index),"");
|
||||||
song.systemFlags[index].loadFromBase64(flags.c_str());
|
song.systemFlags[index].loadFromBase64(flags.c_str());
|
||||||
}
|
}
|
||||||
|
@ -1675,8 +1683,9 @@ bool DivEngine::addSystem(DivSystem which) {
|
||||||
BUSY_BEGIN;
|
BUSY_BEGIN;
|
||||||
saveLock.lock();
|
saveLock.lock();
|
||||||
song.system[song.systemLen]=which;
|
song.system[song.systemLen]=which;
|
||||||
song.systemVol[song.systemLen]=64;
|
song.systemVol[song.systemLen]=1.0;
|
||||||
song.systemPan[song.systemLen]=0;
|
song.systemPan[song.systemLen]=0;
|
||||||
|
song.systemPanFR[song.systemLen]=0;
|
||||||
song.systemFlags[song.systemLen++].clear();
|
song.systemFlags[song.systemLen++].clear();
|
||||||
recalcChans();
|
recalcChans();
|
||||||
saveLock.unlock();
|
saveLock.unlock();
|
||||||
|
@ -1721,6 +1730,7 @@ bool DivEngine::removeSystem(int index, bool preserveOrder) {
|
||||||
song.system[i]=song.system[i+1];
|
song.system[i]=song.system[i+1];
|
||||||
song.systemVol[i]=song.systemVol[i+1];
|
song.systemVol[i]=song.systemVol[i+1];
|
||||||
song.systemPan[i]=song.systemPan[i+1];
|
song.systemPan[i]=song.systemPan[i+1];
|
||||||
|
song.systemPanFR[i]=song.systemPanFR[i+1];
|
||||||
song.systemFlags[i]=song.systemFlags[i+1];
|
song.systemFlags[i]=song.systemFlags[i+1];
|
||||||
}
|
}
|
||||||
recalcChans();
|
recalcChans();
|
||||||
|
@ -1835,17 +1845,21 @@ bool DivEngine::swapSystem(int src, int dest, bool preserveOrder) {
|
||||||
}
|
}
|
||||||
|
|
||||||
DivSystem srcSystem=song.system[src];
|
DivSystem srcSystem=song.system[src];
|
||||||
|
float srcVol=song.systemVol[src];
|
||||||
|
float srcPan=song.systemPan[src];
|
||||||
|
float srcPanFR=song.systemPanFR[src];
|
||||||
|
|
||||||
song.system[src]=song.system[dest];
|
song.system[src]=song.system[dest];
|
||||||
song.system[dest]=srcSystem;
|
song.system[dest]=srcSystem;
|
||||||
|
|
||||||
song.systemVol[src]^=song.systemVol[dest];
|
song.systemVol[src]=song.systemVol[dest];
|
||||||
song.systemVol[dest]^=song.systemVol[src];
|
song.systemVol[dest]=srcVol;
|
||||||
song.systemVol[src]^=song.systemVol[dest];
|
|
||||||
|
|
||||||
song.systemPan[src]^=song.systemPan[dest];
|
song.systemPan[src]=song.systemPan[dest];
|
||||||
song.systemPan[dest]^=song.systemPan[src];
|
song.systemPan[dest]=srcPan;
|
||||||
song.systemPan[src]^=song.systemPan[dest];
|
|
||||||
|
song.systemPanFR[src]=song.systemPanFR[dest];
|
||||||
|
song.systemPanFR[dest]=srcPanFR;
|
||||||
|
|
||||||
// I am kinda scared to use std::swap
|
// I am kinda scared to use std::swap
|
||||||
DivConfig oldFlags=song.systemFlags[src];
|
DivConfig oldFlags=song.systemFlags[src];
|
||||||
|
@ -4265,13 +4279,15 @@ bool DivEngine::init() {
|
||||||
if (!hasLoadedSomething) {
|
if (!hasLoadedSomething) {
|
||||||
logD("setting default preset");
|
logD("setting default preset");
|
||||||
String preset=getConfString("initialSys2","");
|
String preset=getConfString("initialSys2","");
|
||||||
|
bool oldVol=getConfInt("configVersion",DIV_ENGINE_VERSION)<135;
|
||||||
if (preset.empty()) {
|
if (preset.empty()) {
|
||||||
// try loading old preset
|
// try loading old preset
|
||||||
preset=decodeSysDesc(getConfString("initialSys",""));
|
preset=decodeSysDesc(getConfString("initialSys",""));
|
||||||
|
oldVol=false;
|
||||||
}
|
}
|
||||||
logD("preset size %ld",preset.size());
|
logD("preset size %ld",preset.size());
|
||||||
if (preset.size()>0 && (preset.size()&3)==0) {
|
if (preset.size()>0 && (preset.size()&3)==0) {
|
||||||
initSongWithDesc(preset.c_str());
|
initSongWithDesc(preset.c_str(),true,oldVol);
|
||||||
}
|
}
|
||||||
String sysName=getConfString("initialSysName","");
|
String sysName=getConfString("initialSysName","");
|
||||||
if (sysName=="") {
|
if (sysName=="") {
|
||||||
|
|
|
@ -47,8 +47,8 @@
|
||||||
#define BUSY_BEGIN_SOFT softLocked=true; isBusy.lock();
|
#define BUSY_BEGIN_SOFT softLocked=true; isBusy.lock();
|
||||||
#define BUSY_END isBusy.unlock(); softLocked=false;
|
#define BUSY_END isBusy.unlock(); softLocked=false;
|
||||||
|
|
||||||
#define DIV_VERSION "dev134"
|
#define DIV_VERSION "dev135"
|
||||||
#define DIV_ENGINE_VERSION 134
|
#define DIV_ENGINE_VERSION 135
|
||||||
// for imports
|
// for imports
|
||||||
#define DIV_VERSION_MOD 0xff01
|
#define DIV_VERSION_MOD 0xff01
|
||||||
#define DIV_VERSION_FC 0xff02
|
#define DIV_VERSION_FC 0xff02
|
||||||
|
@ -476,7 +476,7 @@ class DivEngine {
|
||||||
bool deinitAudioBackend(bool dueToSwitchMaster=false);
|
bool deinitAudioBackend(bool dueToSwitchMaster=false);
|
||||||
|
|
||||||
void registerSystems();
|
void registerSystems();
|
||||||
void initSongWithDesc(const char* description, bool inBase64=true);
|
void initSongWithDesc(const char* description, bool inBase64=true, bool oldVol=false);
|
||||||
|
|
||||||
void exchangeIns(int one, int two);
|
void exchangeIns(int one, int two);
|
||||||
void swapChannels(int src, int dest);
|
void swapChannels(int src, int dest);
|
||||||
|
|
|
@ -939,13 +939,13 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
||||||
ds.systemLen=2;
|
ds.systemLen=2;
|
||||||
ds.system[0]=DIV_SYSTEM_YM2612;
|
ds.system[0]=DIV_SYSTEM_YM2612;
|
||||||
ds.system[1]=DIV_SYSTEM_SMS;
|
ds.system[1]=DIV_SYSTEM_SMS;
|
||||||
ds.systemVol[1]=32;
|
ds.systemVol[1]=0.5f;
|
||||||
}
|
}
|
||||||
if (ds.system[0]==DIV_SYSTEM_GENESIS_EXT) {
|
if (ds.system[0]==DIV_SYSTEM_GENESIS_EXT) {
|
||||||
ds.systemLen=2;
|
ds.systemLen=2;
|
||||||
ds.system[0]=DIV_SYSTEM_YM2612_EXT;
|
ds.system[0]=DIV_SYSTEM_YM2612_EXT;
|
||||||
ds.system[1]=DIV_SYSTEM_SMS;
|
ds.system[1]=DIV_SYSTEM_SMS;
|
||||||
ds.systemVol[1]=32;
|
ds.systemVol[1]=0.5f;
|
||||||
}
|
}
|
||||||
if (ds.system[0]==DIV_SYSTEM_ARCADE) {
|
if (ds.system[0]==DIV_SYSTEM_ARCADE) {
|
||||||
ds.systemLen=2;
|
ds.systemLen=2;
|
||||||
|
@ -1830,14 +1830,18 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
|
||||||
|
|
||||||
// system volume
|
// system volume
|
||||||
for (int i=0; i<DIV_MAX_CHIPS; i++) {
|
for (int i=0; i<DIV_MAX_CHIPS; i++) {
|
||||||
ds.systemVol[i]=reader.readC();
|
signed char oldSysVol=reader.readC();
|
||||||
|
ds.systemVol[i]=(float)oldSysVol/64.0f;
|
||||||
if (ds.version<59 && ds.system[i]==DIV_SYSTEM_NES) {
|
if (ds.version<59 && ds.system[i]==DIV_SYSTEM_NES) {
|
||||||
ds.systemVol[i]/=4;
|
ds.systemVol[i]/=4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// system panning
|
// system panning
|
||||||
for (int i=0; i<DIV_MAX_CHIPS; i++) ds.systemPan[i]=reader.readC();
|
for (int i=0; i<DIV_MAX_CHIPS; i++) {
|
||||||
|
signed char oldSysPan=reader.readC();
|
||||||
|
ds.systemPan[i]=(float)oldSysPan/127.0f;
|
||||||
|
}
|
||||||
|
|
||||||
// system props
|
// system props
|
||||||
for (int i=0; i<DIV_MAX_CHIPS; i++) {
|
for (int i=0; i<DIV_MAX_CHIPS; i++) {
|
||||||
|
@ -1860,14 +1864,14 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
|
||||||
ds.system[i]=DIV_SYSTEM_YM2612;
|
ds.system[i]=DIV_SYSTEM_YM2612;
|
||||||
if (i<31) {
|
if (i<31) {
|
||||||
ds.system[i+1]=DIV_SYSTEM_SMS;
|
ds.system[i+1]=DIV_SYSTEM_SMS;
|
||||||
ds.systemVol[i+1]=(((ds.systemVol[i]&127)*3)>>3)|(ds.systemVol[i]&128);
|
ds.systemVol[i+1]=ds.systemVol[i]*0.375f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ds.system[i]==DIV_SYSTEM_GENESIS_EXT) {
|
if (ds.system[i]==DIV_SYSTEM_GENESIS_EXT) {
|
||||||
ds.system[i]=DIV_SYSTEM_YM2612_EXT;
|
ds.system[i]=DIV_SYSTEM_YM2612_EXT;
|
||||||
if (i<31) {
|
if (i<31) {
|
||||||
ds.system[i+1]=DIV_SYSTEM_SMS;
|
ds.system[i+1]=DIV_SYSTEM_SMS;
|
||||||
ds.systemVol[i+1]=(((ds.systemVol[i]&127)*3)>>3)|(ds.systemVol[i]&128);
|
ds.systemVol[i+1]=ds.systemVol[i]*0.375f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ds.system[i]==DIV_SYSTEM_ARCADE) {
|
if (ds.system[i]==DIV_SYSTEM_ARCADE) {
|
||||||
|
@ -2200,6 +2204,21 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
|
||||||
ds.autoSystem=true;
|
ds.autoSystem=true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// system output config
|
||||||
|
if (ds.version>=135) {
|
||||||
|
for (int i=0; i<ds.systemLen; i++) {
|
||||||
|
ds.systemVol[i]=reader.readF();
|
||||||
|
ds.systemPan[i]=reader.readF();
|
||||||
|
ds.systemPanFR[i]=reader.readF();
|
||||||
|
}
|
||||||
|
|
||||||
|
// patchbay
|
||||||
|
unsigned int conns=reader.readI();
|
||||||
|
for (unsigned int i=0; i<conns; i++) {
|
||||||
|
ds.patchbay.push_back((unsigned int)reader.readI());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// read system flags
|
// read system flags
|
||||||
if (ds.version>=119) {
|
if (ds.version>=119) {
|
||||||
logD("reading chip flags...");
|
logD("reading chip flags...");
|
||||||
|
@ -4308,11 +4327,11 @@ SafeWriter* DivEngine::saveFur(bool notPrimary) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i=0; i<DIV_MAX_CHIPS; i++) {
|
for (int i=0; i<DIV_MAX_CHIPS; i++) {
|
||||||
w->writeC(song.systemVol[i]);
|
w->writeC(song.systemVol[i]*64.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i=0; i<DIV_MAX_CHIPS; i++) {
|
for (int i=0; i<DIV_MAX_CHIPS; i++) {
|
||||||
w->writeC(song.systemPan[i]);
|
w->writeC(song.systemPan[i]*127.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
// chip flags (we'll seek here later)
|
// chip flags (we'll seek here later)
|
||||||
|
@ -4456,6 +4475,17 @@ SafeWriter* DivEngine::saveFur(bool notPrimary) {
|
||||||
w->writeString(song.systemNameJ,false);
|
w->writeString(song.systemNameJ,false);
|
||||||
w->writeString(song.categoryJ,false);
|
w->writeString(song.categoryJ,false);
|
||||||
|
|
||||||
|
// system output config
|
||||||
|
for (int i=0; i<song.systemLen; i++) {
|
||||||
|
w->writeF(song.systemVol[i]);
|
||||||
|
w->writeF(song.systemPan[i]);
|
||||||
|
w->writeF(song.systemPanFR[i]);
|
||||||
|
}
|
||||||
|
w->writeI(song.patchbay.size());
|
||||||
|
for (unsigned int i: song.patchbay) {
|
||||||
|
w->writeI(i);
|
||||||
|
}
|
||||||
|
|
||||||
blockEndSeek=w->tell();
|
blockEndSeek=w->tell();
|
||||||
w->seek(blockStartSeek,SEEK_SET);
|
w->seek(blockStartSeek,SEEK_SET);
|
||||||
w->writeI(blockEndSeek-blockStartSeek-4);
|
w->writeI(blockEndSeek-blockStartSeek-4);
|
||||||
|
|
|
@ -1720,10 +1720,10 @@ void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsi
|
||||||
disCont[i].fillBuf(disCont[i].runtotal,disCont[i].lastAvail,size-disCont[i].lastAvail);
|
disCont[i].fillBuf(disCont[i].runtotal,disCont[i].lastAvail,size-disCont[i].lastAvail);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: handle more than 2 outputs
|
// TODO: patchbay
|
||||||
for (int i=0; i<song.systemLen; i++) {
|
for (int i=0; i<song.systemLen; i++) {
|
||||||
float volL=((float)song.systemVol[i]/64.0f)*((float)MIN(127,127-(int)song.systemPan[i])/127.0f)*song.masterVol;
|
float volL=song.systemVol[i]*MIN(1.0f,1.0f-song.systemPan[i])*song.masterVol;
|
||||||
float volR=((float)song.systemVol[i]/64.0f)*((float)MIN(127,127+(int)song.systemPan[i])/127.0f)*song.masterVol;
|
float volR=song.systemVol[i]*MIN(1.0f,1.0f+song.systemPan[i])*song.masterVol;
|
||||||
volL*=disCont[i].dispatch->getPostAmp();
|
volL*=disCont[i].dispatch->getPostAmp();
|
||||||
volR*=disCont[i].dispatch->getPostAmp();
|
volR*=disCont[i].dispatch->getPostAmp();
|
||||||
if (disCont[i].dispatch->getOutputCount()>1) {
|
if (disCont[i].dispatch->getOutputCount()>1) {
|
||||||
|
|
|
@ -238,8 +238,9 @@ struct DivSong {
|
||||||
// system
|
// system
|
||||||
DivSystem system[DIV_MAX_CHIPS];
|
DivSystem system[DIV_MAX_CHIPS];
|
||||||
unsigned char systemLen;
|
unsigned char systemLen;
|
||||||
signed char systemVol[DIV_MAX_CHIPS];
|
float systemVol[DIV_MAX_CHIPS];
|
||||||
signed char systemPan[DIV_MAX_CHIPS];
|
float systemPan[DIV_MAX_CHIPS];
|
||||||
|
float systemPanFR[DIV_MAX_CHIPS];
|
||||||
DivConfig systemFlags[DIV_MAX_CHIPS];
|
DivConfig systemFlags[DIV_MAX_CHIPS];
|
||||||
|
|
||||||
// song information
|
// song information
|
||||||
|
@ -334,6 +335,7 @@ struct DivSong {
|
||||||
std::vector<DivSample*> sample;
|
std::vector<DivSample*> sample;
|
||||||
|
|
||||||
std::vector<DivSubSong*> subsong;
|
std::vector<DivSubSong*> subsong;
|
||||||
|
std::vector<unsigned int> patchbay;
|
||||||
|
|
||||||
DivInstrument nullIns, nullInsOPLL, nullInsOPL, nullInsOPLDrums, nullInsQSound;
|
DivInstrument nullIns, nullInsOPLL, nullInsOPL, nullInsOPLDrums, nullInsQSound;
|
||||||
DivWavetable nullWave;
|
DivWavetable nullWave;
|
||||||
|
@ -438,8 +440,9 @@ struct DivSong {
|
||||||
oldArpStrategy(false) {
|
oldArpStrategy(false) {
|
||||||
for (int i=0; i<DIV_MAX_CHIPS; i++) {
|
for (int i=0; i<DIV_MAX_CHIPS; i++) {
|
||||||
system[i]=DIV_SYSTEM_NULL;
|
system[i]=DIV_SYSTEM_NULL;
|
||||||
systemVol[i]=64;
|
systemVol[i]=1.0;
|
||||||
systemPan[i]=0;
|
systemPan[i]=0.0;
|
||||||
|
systemPanFR[i]=0.0;
|
||||||
}
|
}
|
||||||
subsong.push_back(new DivSubSong);
|
subsong.push_back(new DivSubSong);
|
||||||
system[0]=DIV_SYSTEM_YM2612;
|
system[0]=DIV_SYSTEM_YM2612;
|
||||||
|
|
|
@ -935,9 +935,9 @@ struct Gradient2D {
|
||||||
|
|
||||||
struct FurnaceGUISysDefChip {
|
struct FurnaceGUISysDefChip {
|
||||||
DivSystem sys;
|
DivSystem sys;
|
||||||
int vol, pan;
|
float vol, pan;
|
||||||
const char* flags;
|
const char* flags;
|
||||||
FurnaceGUISysDefChip(DivSystem s, int v, int p, const char* f):
|
FurnaceGUISysDefChip(DivSystem s, float v, float p, const char* f):
|
||||||
sys(s),
|
sys(s),
|
||||||
vol(v),
|
vol(v),
|
||||||
pan(p),
|
pan(p),
|
||||||
|
|
|
@ -37,22 +37,35 @@ void FurnaceGUI::drawMixer() {
|
||||||
} rightClickable
|
} rightClickable
|
||||||
for (int i=0; i<e->song.systemLen; i++) {
|
for (int i=0; i<e->song.systemLen; i++) {
|
||||||
snprintf(id,31,"MixS%d",i);
|
snprintf(id,31,"MixS%d",i);
|
||||||
bool doInvert=e->song.systemVol[i]&128;
|
bool doInvert=e->song.systemVol[i]<0;
|
||||||
signed char vol=e->song.systemVol[i]&127;
|
float vol=fabs(e->song.systemVol[i]);
|
||||||
ImGui::PushID(id);
|
ImGui::PushID(id);
|
||||||
ImGui::Text("%d. %s",i+1,getSystemName(e->song.system[i]));
|
ImGui::Text("%d. %s",i+1,getSystemName(e->song.system[i]));
|
||||||
ImGui::SameLine(ImGui::GetWindowWidth()-(82.0f*dpiScale));
|
ImGui::SameLine(ImGui::GetWindowWidth()-(82.0f*dpiScale));
|
||||||
if (ImGui::Checkbox("Invert",&doInvert)) {
|
if (ImGui::Checkbox("Invert",&doInvert)) {
|
||||||
e->song.systemVol[i]^=128;
|
e->song.systemVol[i]=-e->song.systemVol[i];
|
||||||
MARK_MODIFIED;
|
MARK_MODIFIED;
|
||||||
}
|
}
|
||||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x-(50.0f*dpiScale));
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||||
if (CWSliderScalar("Volume",ImGuiDataType_S8,&vol,&_ZERO,&_ONE_HUNDRED_TWENTY_SEVEN)) {
|
if (CWSliderFloat("Volume",&vol,0,2)) {
|
||||||
e->song.systemVol[i]=(e->song.systemVol[i]&128)|vol;
|
if (doInvert) {
|
||||||
|
if (vol<0.0001) vol=0.0001;
|
||||||
|
}
|
||||||
|
if (vol<0) vol=0;
|
||||||
|
if (vol>10) vol=10;
|
||||||
|
e->song.systemVol[i]=(doInvert)?-vol:vol;
|
||||||
MARK_MODIFIED;
|
MARK_MODIFIED;
|
||||||
} rightClickable
|
} rightClickable
|
||||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x-(50.0f*dpiScale));
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||||
if (CWSliderScalar("Panning",ImGuiDataType_S8,&e->song.systemPan[i],&_MINUS_ONE_HUNDRED_TWENTY_SEVEN,&_ONE_HUNDRED_TWENTY_SEVEN)) {
|
if (CWSliderFloat("Panning",&e->song.systemPan[i],-1.0f,1.0f)) {
|
||||||
|
if (e->song.systemPan[i]<-1.0f) e->song.systemPan[i]=-1.0f;
|
||||||
|
if (e->song.systemPan[i]>1.0f) e->song.systemPan[i]=1.0f;
|
||||||
|
MARK_MODIFIED;
|
||||||
|
} rightClickable
|
||||||
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||||
|
if (CWSliderFloat("Front/Rear",&e->song.systemPanFR[i],-1.0f,1.0f)) {
|
||||||
|
if (e->song.systemPanFR[i]<-1.0f) e->song.systemPanFR[i]=-1.0f;
|
||||||
|
if (e->song.systemPanFR[i]>1.0f) e->song.systemPanFR[i]=1.0f;
|
||||||
MARK_MODIFIED;
|
MARK_MODIFIED;
|
||||||
} rightClickable
|
} rightClickable
|
||||||
|
|
||||||
|
|
1552
src/gui/presets.cpp
1552
src/gui/presets.cpp
File diff suppressed because it is too large
Load diff
|
@ -309,8 +309,9 @@ void FurnaceGUI::drawSettings() {
|
||||||
settings.initialSys.clear();
|
settings.initialSys.clear();
|
||||||
for (int i=0; i<e->song.systemLen; i++) {
|
for (int i=0; i<e->song.systemLen; i++) {
|
||||||
settings.initialSys.set(fmt::sprintf("id%d",i),e->systemToFileFur(e->song.system[i]));
|
settings.initialSys.set(fmt::sprintf("id%d",i),e->systemToFileFur(e->song.system[i]));
|
||||||
settings.initialSys.set(fmt::sprintf("vol%d",i),(int)e->song.systemVol[i]);
|
settings.initialSys.set(fmt::sprintf("vol%d",i),(float)e->song.systemVol[i]);
|
||||||
settings.initialSys.set(fmt::sprintf("pan%d",i),(int)e->song.systemPan[i]);
|
settings.initialSys.set(fmt::sprintf("pan%d",i),(float)e->song.systemPan[i]);
|
||||||
|
settings.initialSys.set(fmt::sprintf("fr%d",i),(float)e->song.systemPanFR[i]);
|
||||||
settings.initialSys.set(fmt::sprintf("flags%d",i),e->song.systemFlags[i].toBase64());
|
settings.initialSys.set(fmt::sprintf("flags%d",i),e->song.systemFlags[i].toBase64());
|
||||||
}
|
}
|
||||||
settings.initialSysName=e->song.systemName;
|
settings.initialSysName=e->song.systemName;
|
||||||
|
@ -324,14 +325,16 @@ void FurnaceGUI::drawSettings() {
|
||||||
if (totalAvailSys>0) {
|
if (totalAvailSys>0) {
|
||||||
for (int i=0; i<howMany; i++) {
|
for (int i=0; i<howMany; i++) {
|
||||||
settings.initialSys.set(fmt::sprintf("id%d",i),e->systemToFileFur((DivSystem)availableSystems[rand()%totalAvailSys]));
|
settings.initialSys.set(fmt::sprintf("id%d",i),e->systemToFileFur((DivSystem)availableSystems[rand()%totalAvailSys]));
|
||||||
settings.initialSys.set(fmt::sprintf("vol%d",i),64);
|
settings.initialSys.set(fmt::sprintf("vol%d",i),1.0f);
|
||||||
settings.initialSys.set(fmt::sprintf("pan%d",i),0);
|
settings.initialSys.set(fmt::sprintf("pan%d",i),0.0f);
|
||||||
|
settings.initialSys.set(fmt::sprintf("fr%d",i),0.0f);
|
||||||
settings.initialSys.set(fmt::sprintf("flags%d",i),"");
|
settings.initialSys.set(fmt::sprintf("flags%d",i),"");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
settings.initialSys.set("id0",e->systemToFileFur(DIV_SYSTEM_DUMMY));
|
settings.initialSys.set("id0",e->systemToFileFur(DIV_SYSTEM_DUMMY));
|
||||||
settings.initialSys.set("vol0",64);
|
settings.initialSys.set("vol0",1.0f);
|
||||||
settings.initialSys.set("pan0",0);
|
settings.initialSys.set("pan0",0.0f);
|
||||||
|
settings.initialSys.set("fr0",0.0f);
|
||||||
settings.initialSys.set("flags0","");
|
settings.initialSys.set("flags0","");
|
||||||
howMany=1;
|
howMany=1;
|
||||||
}
|
}
|
||||||
|
@ -366,12 +369,14 @@ void FurnaceGUI::drawSettings() {
|
||||||
if (ImGui::Button("Reset to defaults")) {
|
if (ImGui::Button("Reset to defaults")) {
|
||||||
settings.initialSys.clear();
|
settings.initialSys.clear();
|
||||||
settings.initialSys.set("id0",e->systemToFileFur(DIV_SYSTEM_YM2612));
|
settings.initialSys.set("id0",e->systemToFileFur(DIV_SYSTEM_YM2612));
|
||||||
settings.initialSys.set("vol0",64);
|
settings.initialSys.set("vol0",1.0f);
|
||||||
settings.initialSys.set("pan0",0);
|
settings.initialSys.set("pan0",0.0f);
|
||||||
|
settings.initialSys.set("fr0",0.0f);
|
||||||
settings.initialSys.set("flags0","");
|
settings.initialSys.set("flags0","");
|
||||||
settings.initialSys.set("id1",e->systemToFileFur(DIV_SYSTEM_SMS));
|
settings.initialSys.set("id1",e->systemToFileFur(DIV_SYSTEM_SMS));
|
||||||
settings.initialSys.set("vol1",32);
|
settings.initialSys.set("vol1",0.5f);
|
||||||
settings.initialSys.set("pan1",0);
|
settings.initialSys.set("pan1",0.0f);
|
||||||
|
settings.initialSys.set("fr1",0.0f);
|
||||||
settings.initialSys.set("flags1","");
|
settings.initialSys.set("flags1","");
|
||||||
settings.initialSysName="Sega Genesis/Mega Drive";
|
settings.initialSysName="Sega Genesis/Mega Drive";
|
||||||
}
|
}
|
||||||
|
@ -385,14 +390,15 @@ void FurnaceGUI::drawSettings() {
|
||||||
int doRemove=-1;
|
int doRemove=-1;
|
||||||
for (size_t i=0; settings.initialSys.getInt(fmt::sprintf("id%d",i),0); i++) {
|
for (size_t i=0; settings.initialSys.getInt(fmt::sprintf("id%d",i),0); i++) {
|
||||||
DivSystem sysID=e->systemFromFileFur(settings.initialSys.getInt(fmt::sprintf("id%d",i),0));
|
DivSystem sysID=e->systemFromFileFur(settings.initialSys.getInt(fmt::sprintf("id%d",i),0));
|
||||||
signed char sysVol=settings.initialSys.getInt(fmt::sprintf("vol%d",i),0);
|
float sysVol=settings.initialSys.getFloat(fmt::sprintf("vol%d",i),0);
|
||||||
signed char sysPan=settings.initialSys.getInt(fmt::sprintf("pan%d",i),0);
|
float sysPan=settings.initialSys.getFloat(fmt::sprintf("pan%d",i),0);
|
||||||
|
float sysPanFR=settings.initialSys.getFloat(fmt::sprintf("fr%d",i),0);
|
||||||
|
|
||||||
sysCount=i+1;
|
sysCount=i+1;
|
||||||
|
|
||||||
//bool doRemove=false;
|
//bool doRemove=false;
|
||||||
bool doInvert=sysVol&128;
|
bool doInvert=(sysVol<0);
|
||||||
signed char vol=sysVol&127;
|
float vol=fabs(sysVol);
|
||||||
ImGui::PushID(i);
|
ImGui::PushID(i);
|
||||||
|
|
||||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x-ImGui::CalcTextSize("Invert").x-ImGui::GetFrameHeightWithSpacing()*2.0-ImGui::GetStyle().ItemSpacing.x);
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x-ImGui::CalcTextSize("Invert").x-ImGui::GetFrameHeightWithSpacing()*2.0-ImGui::GetStyle().ItemSpacing.x);
|
||||||
|
@ -409,8 +415,8 @@ void FurnaceGUI::drawSettings() {
|
||||||
|
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (ImGui::Checkbox("Invert",&doInvert)) {
|
if (ImGui::Checkbox("Invert",&doInvert)) {
|
||||||
sysVol^=128;
|
sysVol=-sysVol;
|
||||||
settings.initialSys.set(fmt::sprintf("vol%d",i),(int)sysVol);
|
settings.initialSys.set(fmt::sprintf("vol%d",i),sysVol);
|
||||||
}
|
}
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
//ImGui::BeginDisabled(settings.initialSys.size()<=4);
|
//ImGui::BeginDisabled(settings.initialSys.size()<=4);
|
||||||
|
@ -418,14 +424,27 @@ void FurnaceGUI::drawSettings() {
|
||||||
doRemove=i;
|
doRemove=i;
|
||||||
}
|
}
|
||||||
//ImGui::EndDisabled();
|
//ImGui::EndDisabled();
|
||||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x-(50.0f*dpiScale));
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||||
if (CWSliderScalar("Volume",ImGuiDataType_S8,&vol,&_ZERO,&_ONE_HUNDRED_TWENTY_SEVEN)) {
|
if (CWSliderFloat("Volume",&vol,0.0f,3.0f)) {
|
||||||
sysVol=(sysVol&128)|vol;
|
if (doInvert) {
|
||||||
settings.initialSys.set(fmt::sprintf("vol%d",i),(int)sysVol);
|
if (vol<0.0001) vol=0.0001;
|
||||||
|
}
|
||||||
|
if (vol<0) vol=0;
|
||||||
|
if (vol>10) vol=10;
|
||||||
|
sysVol=doInvert?-vol:vol;
|
||||||
|
settings.initialSys.set(fmt::sprintf("vol%d",i),(float)sysVol);
|
||||||
} rightClickable
|
} rightClickable
|
||||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x-(50.0f*dpiScale));
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||||
if (CWSliderScalar("Panning",ImGuiDataType_S8,&sysPan,&_MINUS_ONE_HUNDRED_TWENTY_SEVEN,&_ONE_HUNDRED_TWENTY_SEVEN)) {
|
if (CWSliderFloat("Panning",&sysPan,-1.0f,1.0f)) {
|
||||||
settings.initialSys.set(fmt::sprintf("pan%d",i),(int)sysPan);
|
if (sysPan<-1.0f) sysPan=-1.0f;
|
||||||
|
if (sysPan>1.0f) sysPan=1.0f;
|
||||||
|
settings.initialSys.set(fmt::sprintf("pan%d",i),(float)sysPan);
|
||||||
|
} rightClickable
|
||||||
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||||
|
if (CWSliderFloat("Front/Rear",&sysPanFR,-1.0f,1.0f)) {
|
||||||
|
if (sysPanFR<-1.0f) sysPanFR=-1.0f;
|
||||||
|
if (sysPanFR>1.0f) sysPanFR=1.0f;
|
||||||
|
settings.initialSys.set(fmt::sprintf("fr%d",i),(float)sysPanFR);
|
||||||
} rightClickable
|
} rightClickable
|
||||||
|
|
||||||
// oh please MSVC don't cry
|
// oh please MSVC don't cry
|
||||||
|
@ -445,25 +464,29 @@ void FurnaceGUI::drawSettings() {
|
||||||
if (doRemove>=0 && sysCount>1) {
|
if (doRemove>=0 && sysCount>1) {
|
||||||
for (int i=doRemove; i<sysCount-1; i++) {
|
for (int i=doRemove; i<sysCount-1; i++) {
|
||||||
int sysID=settings.initialSys.getInt(fmt::sprintf("id%d",i+1),0);
|
int sysID=settings.initialSys.getInt(fmt::sprintf("id%d",i+1),0);
|
||||||
int sysVol=settings.initialSys.getInt(fmt::sprintf("vol%d",i+1),0);
|
float sysVol=settings.initialSys.getFloat(fmt::sprintf("vol%d",i+1),0);
|
||||||
int sysPan=settings.initialSys.getInt(fmt::sprintf("pan%d",i+1),0);
|
float sysPan=settings.initialSys.getFloat(fmt::sprintf("pan%d",i+1),0);
|
||||||
|
float sysPanFR=settings.initialSys.getFloat(fmt::sprintf("fr%d",i+1),0);
|
||||||
String sysFlags=settings.initialSys.getString(fmt::sprintf("flags%d",i+1),"");
|
String sysFlags=settings.initialSys.getString(fmt::sprintf("flags%d",i+1),"");
|
||||||
settings.initialSys.set(fmt::sprintf("id%d",i),sysID);
|
settings.initialSys.set(fmt::sprintf("id%d",i),sysID);
|
||||||
settings.initialSys.set(fmt::sprintf("vol%d",i),sysVol);
|
settings.initialSys.set(fmt::sprintf("vol%d",i),sysVol);
|
||||||
settings.initialSys.set(fmt::sprintf("pan%d",i),sysPan);
|
settings.initialSys.set(fmt::sprintf("pan%d",i),sysPan);
|
||||||
|
settings.initialSys.set(fmt::sprintf("fr%d",i),sysPanFR);
|
||||||
settings.initialSys.set(fmt::sprintf("flags%d",i),sysFlags);
|
settings.initialSys.set(fmt::sprintf("flags%d",i),sysFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
settings.initialSys.remove(fmt::sprintf("id%d",sysCount-1));
|
settings.initialSys.remove(fmt::sprintf("id%d",sysCount-1));
|
||||||
settings.initialSys.remove(fmt::sprintf("vol%d",sysCount-1));
|
settings.initialSys.remove(fmt::sprintf("vol%d",sysCount-1));
|
||||||
settings.initialSys.remove(fmt::sprintf("pan%d",sysCount-1));
|
settings.initialSys.remove(fmt::sprintf("pan%d",sysCount-1));
|
||||||
|
settings.initialSys.remove(fmt::sprintf("fr%d",sysCount-1));
|
||||||
settings.initialSys.remove(fmt::sprintf("flags%d",sysCount-1));
|
settings.initialSys.remove(fmt::sprintf("flags%d",sysCount-1));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sysCount<32) if (ImGui::Button(ICON_FA_PLUS "##InitSysAdd")) {
|
if (sysCount<32) if (ImGui::Button(ICON_FA_PLUS "##InitSysAdd")) {
|
||||||
settings.initialSys.set(fmt::sprintf("id%d",sysCount),(int)e->systemToFileFur(DIV_SYSTEM_YM2612));
|
settings.initialSys.set(fmt::sprintf("id%d",sysCount),(int)e->systemToFileFur(DIV_SYSTEM_YM2612));
|
||||||
settings.initialSys.set(fmt::sprintf("vol%d",sysCount),64);
|
settings.initialSys.set(fmt::sprintf("vol%d",sysCount),1.0f);
|
||||||
settings.initialSys.set(fmt::sprintf("pan%d",sysCount),0);
|
settings.initialSys.set(fmt::sprintf("pan%d",sysCount),0.0f);
|
||||||
|
settings.initialSys.set(fmt::sprintf("fr%d",sysCount),0.0f);
|
||||||
settings.initialSys.set(fmt::sprintf("flags%d",sysCount),"");
|
settings.initialSys.set(fmt::sprintf("flags%d",sysCount),"");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2633,21 +2656,36 @@ void FurnaceGUI::syncSettings() {
|
||||||
if (settings.exportFadeOut<0.0) settings.exportFadeOut=0.0;
|
if (settings.exportFadeOut<0.0) settings.exportFadeOut=0.0;
|
||||||
|
|
||||||
String initialSys2=e->getConfString("initialSys2","");
|
String initialSys2=e->getConfString("initialSys2","");
|
||||||
|
bool oldVol=e->getConfInt("configVersion",DIV_ENGINE_VERSION)<135;
|
||||||
if (initialSys2.empty()) {
|
if (initialSys2.empty()) {
|
||||||
initialSys2=e->decodeSysDesc(e->getConfString("initialSys",""));
|
initialSys2=e->decodeSysDesc(e->getConfString("initialSys",""));
|
||||||
|
oldVol=false;
|
||||||
}
|
}
|
||||||
settings.initialSys.clear();
|
settings.initialSys.clear();
|
||||||
settings.initialSys.loadFromBase64(initialSys2.c_str());
|
settings.initialSys.loadFromBase64(initialSys2.c_str());
|
||||||
if (settings.initialSys.getInt("id0",0)==0) {
|
if (settings.initialSys.getInt("id0",0)==0) {
|
||||||
settings.initialSys.clear();
|
settings.initialSys.clear();
|
||||||
settings.initialSys.set("id0",e->systemToFileFur(DIV_SYSTEM_YM2612));
|
settings.initialSys.set("id0",e->systemToFileFur(DIV_SYSTEM_YM2612));
|
||||||
settings.initialSys.set("vol0",64);
|
settings.initialSys.set("vol0",1.0f);
|
||||||
settings.initialSys.set("pan0",0);
|
settings.initialSys.set("pan0",0.0f);
|
||||||
|
settings.initialSys.set("fr0",0.0f);
|
||||||
settings.initialSys.set("flags0","");
|
settings.initialSys.set("flags0","");
|
||||||
settings.initialSys.set("id1",e->systemToFileFur(DIV_SYSTEM_SMS));
|
settings.initialSys.set("id1",e->systemToFileFur(DIV_SYSTEM_SMS));
|
||||||
settings.initialSys.set("vol1",64);
|
settings.initialSys.set("vol1",0.5f);
|
||||||
settings.initialSys.set("pan1",0);
|
settings.initialSys.set("pan1",0);
|
||||||
|
settings.initialSys.set("fr1",0);
|
||||||
settings.initialSys.set("flags1","");
|
settings.initialSys.set("flags1","");
|
||||||
|
} else {
|
||||||
|
if (oldVol) {
|
||||||
|
for (int i=0; settings.initialSys.getInt(fmt::sprintf("id%d",i),0); i++) {
|
||||||
|
float newVol=settings.initialSys.getInt(fmt::sprintf("vol%d",i),64);
|
||||||
|
float newPan=settings.initialSys.getInt(fmt::sprintf("pan%d",i),0);
|
||||||
|
newVol/=64.0f;
|
||||||
|
newPan/=127.0f;
|
||||||
|
settings.initialSys.set(fmt::sprintf("vol%d",i),newVol);
|
||||||
|
settings.initialSys.set(fmt::sprintf("pan%d",i),newPan);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// keybinds
|
// keybinds
|
||||||
|
|
Loading…
Reference in a new issue