mirror of
https://github.com/tildearrow/furnace.git
synced 2024-11-30 08:23:01 +00:00
Merge remote-tracking branch 'origin/master' into Mikey_VGM
This commit is contained in:
commit
b42dd554f2
36 changed files with 247 additions and 83 deletions
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
|
@ -11,7 +11,7 @@ defaults:
|
|||
shell: bash
|
||||
|
||||
env:
|
||||
BUILD_TYPE: Release
|
||||
BUILD_TYPE: Debug
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
|
BIN
demos/snes/amalgam.fur
Normal file
BIN
demos/snes/amalgam.fur
Normal file
Binary file not shown.
29
extern/nfd-modified/src/nfd_win.cpp
vendored
29
extern/nfd-modified/src/nfd_win.cpp
vendored
|
@ -30,6 +30,9 @@
|
|||
// hack I know
|
||||
#include "../../../src/utfutils.h"
|
||||
|
||||
// hack 2...
|
||||
#include "../../../src/ta-log.h"
|
||||
|
||||
class NFDWinEvents: public IFileDialogEvents {
|
||||
nfdselcallback_t selCallback;
|
||||
size_t refCount;
|
||||
|
@ -38,21 +41,21 @@ class NFDWinEvents: public IFileDialogEvents {
|
|||
}
|
||||
public:
|
||||
IFACEMETHODIMP QueryInterface(REFIID riid, void** ppv) {
|
||||
printf("QueryInterface called DAMN IT\n");
|
||||
logV("%p: QueryInterface called DAMN IT",(const void*)this);
|
||||
*ppv=NULL;
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP_(ULONG) AddRef() {
|
||||
printf("AddRef() called\n");
|
||||
logV("%p: AddRef() called",(const void*)this);
|
||||
return InterlockedIncrement(&refCount);
|
||||
}
|
||||
|
||||
IFACEMETHODIMP_(ULONG) Release() {
|
||||
printf("Release() called\n");
|
||||
logV("%p: Release() called",(const void*)this);
|
||||
LONG ret=InterlockedDecrement(&refCount);
|
||||
if (ret==0) {
|
||||
printf("Destroying the final object.\n");
|
||||
logV("%p: Destroying the final object.",(const void*)this);
|
||||
delete this;
|
||||
}
|
||||
return ret;
|
||||
|
@ -67,30 +70,40 @@ class NFDWinEvents: public IFileDialogEvents {
|
|||
|
||||
IFACEMETHODIMP OnSelectionChange(IFileDialog* dialog) {
|
||||
// Get the file name
|
||||
logV("%p: OnSelectionChange() called",(const void*)this);
|
||||
::IShellItem *shellItem(NULL);
|
||||
logV("%p: GetCurrentSelection",(const void*)this);
|
||||
HRESULT result = dialog->GetCurrentSelection(&shellItem);
|
||||
if ( !SUCCEEDED(result) )
|
||||
{
|
||||
printf("failure!\n");
|
||||
logV("%p: failure!",(const void*)this);
|
||||
return S_OK;
|
||||
}
|
||||
wchar_t *filePath(NULL);
|
||||
result = shellItem->GetDisplayName(::SIGDN_FILESYSPATH, &filePath);
|
||||
if ( !SUCCEEDED(result) )
|
||||
{
|
||||
printf("GDN failure!\n");
|
||||
logV("%p: GDN failure!",(const void*)this);
|
||||
shellItem->Release();
|
||||
return S_OK;
|
||||
}
|
||||
std::string utf8FilePath=utf16To8(filePath);
|
||||
if (selCallback!=NULL) selCallback(utf8FilePath.c_str());
|
||||
printf("I got you for a value of %s\n",utf8FilePath.c_str());
|
||||
if (selCallback!=NULL) {
|
||||
logV("%p: calling back.",(const void*)this);
|
||||
selCallback(utf8FilePath.c_str());
|
||||
logV("%p: end of callback",(const void*)this);
|
||||
} else {
|
||||
logV("%p: no callback.",(const void*)this);
|
||||
}
|
||||
logV("%p: I got you for a value of %s",(const void*)this,utf8FilePath.c_str());
|
||||
shellItem->Release();
|
||||
logV("%p: shellItem->Release()",(const void*)this);
|
||||
return S_OK;
|
||||
}
|
||||
NFDWinEvents(nfdselcallback_t callback):
|
||||
selCallback(callback),
|
||||
refCount(1) {
|
||||
logV("%p: CONSTRUCT!",(const void*)this);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
BIN
instruments/OPL/2-OP OPL3 Slap Bass.fui
Normal file
BIN
instruments/OPL/2-OP OPL3 Slap Bass.fui
Normal file
Binary file not shown.
|
@ -135,7 +135,7 @@ ex | FM | OPM | OPZ | OPLL | AY-3-8910 | AY8930 | Lynx
|
|||
W | | LFO Shape | LFO Shape | Patch | Waveform | Waveform | | Waveform | Waveform | Waveform | Waveform | Waveform | Waveform | | | | Waveform | |
|
||||
1 | | AMD | AMD | | | Duty | | FilterMode | Envelope | EnvMode | WaveLen | Mod Depth | Cutoff | Filter K1 | ClockDiv | EchoFeedback | Special | GroupAtk |
|
||||
2 | | PMD | PMD | | Envelope | Envelope | | Resonance | | Envelope | WaveUpdate | Mod Speed | Resonance | Filter K2 | | Echo Length | Gain | GroupDec |
|
||||
3 | | LFO Speed | LFO Speed | | AutoEnvNum | AutoEnvNum | | Special | | AutoEnvNum | WaveLoad W | | Control | Env Count | | | | Noise |
|
||||
3 | LFOSpd | LFO Speed | LFO Speed | | AutoEnvNum | AutoEnvNum | | Special | | AutoEnvNum | WaveLoad W | | Control | Env Count | | | | Noise |
|
||||
A | ALG | ALG | ALG | | AutoEnvDen | AutoEnvDen | | | | AutoEnvDen | WaveLoad P | | | Control | | | | |
|
||||
B | FB | FB | FB | | | Noise AND | | | | | WaveLoad L | | | | | | | |
|
||||
C | FMS | FMS | FMS | | | Noise OR | | | | | WaveLoad T | | | | | | | |
|
||||
|
@ -144,4 +144,4 @@ ex | FM | OPM | OPZ | OPLL | AY-3-8910 | AY8930 | Lynx
|
|||
5 | | | AMD2 | | | | | | | | | | | EnvRampR | | | | |
|
||||
6 | | | PMD2 | | | | | | | | | | | EnvRampK1 | | | | |
|
||||
7 | | | LFO2Speed | | | | | | | | | | | EnvRampK2 | | | | |
|
||||
8 | | | LFO2Shape | | | | | | | | | | | Env Mode | | | | |
|
||||
8 | | | LFO2Shape | | | | | | | | | | | Env Mode | | | | |
|
||||
|
|
|
@ -32,6 +32,8 @@ these fields are 0 in format versions prior to 100 (0.6pre1).
|
|||
|
||||
the format versions are:
|
||||
|
||||
- 138: Furnace dev138
|
||||
- 137: Furnace dev137
|
||||
- 136: Furnace dev136
|
||||
- 135: Furnace dev135
|
||||
- 134: Furnace dev134
|
||||
|
@ -398,6 +400,9 @@ size | description
|
|||
4?? | patchbay
|
||||
| - see next section for more details.
|
||||
1 | automatic patchbay (>=136)
|
||||
--- | **a couple more compat flags** (>=138)
|
||||
1 | broken portamento during legato
|
||||
7 | reserved
|
||||
```
|
||||
|
||||
# patchbay
|
||||
|
|
|
@ -58,7 +58,7 @@ bool TAMidiInRtMidi::gather() {
|
|||
if (m.type!=TA_MIDI_SYSEX && msg.size()>1) {
|
||||
memcpy(m.data,msg.data()+1,MIN(msg.size()-1,7));
|
||||
} else if (m.type==TA_MIDI_SYSEX) {
|
||||
m.sysExData.reset(new unsigned char[msg.size()]);
|
||||
m.sysExData=std::shared_ptr<unsigned char>(new unsigned char[msg.size()],std::default_delete<unsigned char[]>());
|
||||
m.sysExLen=msg.size();
|
||||
logD("got a SysEx of length %ld!",msg.size());
|
||||
memcpy(m.sysExData.get(),msg.data(),msg.size());
|
||||
|
|
|
@ -47,8 +47,8 @@
|
|||
#define BUSY_BEGIN_SOFT softLocked=true; isBusy.lock();
|
||||
#define BUSY_END isBusy.unlock(); softLocked=false;
|
||||
|
||||
#define DIV_VERSION "dev136"
|
||||
#define DIV_ENGINE_VERSION 136
|
||||
#define DIV_VERSION "dev138"
|
||||
#define DIV_ENGINE_VERSION 138
|
||||
// for imports
|
||||
#define DIV_VERSION_MOD 0xff01
|
||||
#define DIV_VERSION_FC 0xff02
|
||||
|
|
|
@ -1716,6 +1716,9 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
|
|||
if (ds.version<130) {
|
||||
ds.oldArpStrategy=true;
|
||||
}
|
||||
if (ds.version<138) {
|
||||
ds.brokenPortaLegato=true;
|
||||
}
|
||||
ds.isDMF=false;
|
||||
|
||||
reader.readS(); // reserved
|
||||
|
@ -2221,6 +2224,13 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
|
|||
|
||||
if (ds.version>=136) song.patchbayAuto=reader.readC();
|
||||
|
||||
if (ds.version>=138) {
|
||||
ds.brokenPortaLegato=reader.readC();
|
||||
for (int i=0; i<7; i++) {
|
||||
reader.readC();
|
||||
}
|
||||
}
|
||||
|
||||
// read system flags
|
||||
if (ds.version>=119) {
|
||||
logD("reading chip flags...");
|
||||
|
@ -2574,6 +2584,32 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
|
|||
}
|
||||
}
|
||||
|
||||
// new YM2612/SN/X1-010 volumes
|
||||
if (ds.version<137) {
|
||||
for (int i=0; i<ds.systemLen; i++) {
|
||||
switch (ds.system[i]) {
|
||||
case DIV_SYSTEM_YM2612:
|
||||
case DIV_SYSTEM_YM2612_EXT:
|
||||
case DIV_SYSTEM_YM2612_DUALPCM:
|
||||
case DIV_SYSTEM_YM2612_DUALPCM_EXT:
|
||||
case DIV_SYSTEM_YM2612_CSM:
|
||||
ds.systemVol[i]/=2.0;
|
||||
break;
|
||||
case DIV_SYSTEM_SMS:
|
||||
case DIV_SYSTEM_T6W28:
|
||||
case DIV_SYSTEM_OPLL:
|
||||
case DIV_SYSTEM_OPLL_DRUMS:
|
||||
ds.systemVol[i]/=1.5;
|
||||
break;
|
||||
case DIV_SYSTEM_X1_010:
|
||||
ds.systemVol[i]/=4.0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (active) quitDispatch();
|
||||
BUSY_BEGIN_SOFT;
|
||||
saveLock.lock();
|
||||
|
@ -4489,6 +4525,12 @@ SafeWriter* DivEngine::saveFur(bool notPrimary) {
|
|||
}
|
||||
w->writeC(song.patchbayAuto);
|
||||
|
||||
// even more compat flags
|
||||
w->writeC(song.brokenPortaLegato);
|
||||
for (int i=0; i<7; i++) {
|
||||
w->writeC(0);
|
||||
}
|
||||
|
||||
blockEndSeek=w->tell();
|
||||
w->seek(blockStartSeek,SEEK_SET);
|
||||
w->writeI(blockEndSeek-blockStartSeek-4);
|
||||
|
|
|
@ -83,6 +83,7 @@ class DivPlatformFMBase: public DivDispatch {
|
|||
|
||||
unsigned char lastBusy;
|
||||
int delay;
|
||||
bool flushFirst;
|
||||
|
||||
unsigned char regPool[512];
|
||||
short oldWrites[512];
|
||||
|
@ -102,7 +103,7 @@ class DivPlatformFMBase: public DivDispatch {
|
|||
}
|
||||
}
|
||||
inline void urgentWrite(unsigned short a, unsigned char v) {
|
||||
if (!skipRegisterWrites) {
|
||||
if (!skipRegisterWrites && !flushFirst) {
|
||||
if (writes.empty()) {
|
||||
writes.push_back(QueuedWrite(a,v));
|
||||
} else if (writes.size()>16 || writes.front().addrOrVal) {
|
||||
|
@ -118,9 +119,11 @@ class DivPlatformFMBase: public DivDispatch {
|
|||
|
||||
friend void putDispatchChan(void*,int,int);
|
||||
|
||||
DivPlatformFMBase():DivDispatch(),
|
||||
lastBusy(0),
|
||||
delay(0) {}
|
||||
DivPlatformFMBase():
|
||||
DivDispatch(),
|
||||
lastBusy(0),
|
||||
delay(0),
|
||||
flushFirst(false) {}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -34,7 +34,7 @@ void DivYM2612Interface::ymfm_set_timer(uint32_t tnum, int32_t duration_in_clock
|
|||
} else if (tnum==0) {
|
||||
countA=duration_in_clocks;
|
||||
}
|
||||
logV("ymfm_set_timer(%d,%d)",tnum,duration_in_clocks);
|
||||
//logV("ymfm_set_timer(%d,%d)",tnum,duration_in_clocks);
|
||||
}
|
||||
|
||||
void DivYM2612Interface::clock() {
|
||||
|
@ -141,23 +141,26 @@ void DivPlatformGenesis::acquire_nuked(short** buf, size_t len) {
|
|||
|
||||
os[0]=0; os[1]=0;
|
||||
for (int i=0; i<6; i++) {
|
||||
if (!writes.empty() && --delay<0) {
|
||||
delay=0;
|
||||
QueuedWrite& w=writes.front();
|
||||
if (w.addrOrVal) {
|
||||
OPN2_Write(&fm,0x1+((w.addr>>8)<<1),w.val);
|
||||
//printf("write: %x = %.2x\n",w.addr,w.val);
|
||||
lastBusy=0;
|
||||
regPool[w.addr&0x1ff]=w.val;
|
||||
writes.pop_front();
|
||||
} else {
|
||||
lastBusy++;
|
||||
if (fm.write_busy==0) {
|
||||
//printf("busycounter: %d\n",lastBusy);
|
||||
OPN2_Write(&fm,0x0+((w.addr>>8)<<1),w.addr);
|
||||
w.addrOrVal=true;
|
||||
if (!writes.empty()) {
|
||||
if (--delay<0) {
|
||||
delay=0;
|
||||
QueuedWrite& w=writes.front();
|
||||
if (w.addrOrVal) {
|
||||
//logV("%.3x = %.2x",w.addr,w.val);
|
||||
OPN2_Write(&fm,0x1+((w.addr>>8)<<1),w.val);
|
||||
lastBusy=0;
|
||||
regPool[w.addr&0x1ff]=w.val;
|
||||
writes.pop_front();
|
||||
} else {
|
||||
lastBusy++;
|
||||
if (fm.write_busy==0) {
|
||||
OPN2_Write(&fm,0x0+((w.addr>>8)<<1),w.addr);
|
||||
w.addrOrVal=true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
flushFirst=false;
|
||||
}
|
||||
|
||||
OPN2_Clock(&fm,o); os[0]+=o[0]; os[1]+=o[1];
|
||||
|
@ -207,6 +210,8 @@ void DivPlatformGenesis::acquire_ymfm(short** buf, size_t len) {
|
|||
regPool[w.addr&0x1ff]=w.val;
|
||||
writes.pop_front();
|
||||
lastBusy=1;
|
||||
} else {
|
||||
flushFirst=false;
|
||||
}
|
||||
|
||||
if (ladder) {
|
||||
|
@ -389,6 +394,10 @@ void DivPlatformGenesis::tick(bool sysTick) {
|
|||
chan[i].state.ams=chan[i].std.ams.val;
|
||||
rWrite(chanOffs[i]+ADDR_LRAF,(IS_REALLY_MUTED(i)?0:(chan[i].pan<<6))|(chan[i].state.fms&7)|((chan[i].state.ams&3)<<4));
|
||||
}
|
||||
if (chan[i].std.ex3.had) {
|
||||
lfoValue=(chan[i].std.ex3.val>7)?0:(8|(chan[i].std.ex3.val&7));
|
||||
rWrite(0x22,lfoValue);
|
||||
}
|
||||
if (chan[i].std.ex4.had && chan[i].active) {
|
||||
chan[i].opMask=chan[i].std.ex4.val&15;
|
||||
chan[i].opMaskChanged=true;
|
||||
|
@ -454,6 +463,10 @@ void DivPlatformGenesis::tick(bool sysTick) {
|
|||
|
||||
for (int i=0; i<512; i++) {
|
||||
if (pendingWrites[i]!=oldWrites[i]) {
|
||||
if (i==0x2b && pendingWrites[i]!=0 && !parent->song.brokenDACMode) {
|
||||
if (chan[5].keyOn) chan[5].keyOn=false;
|
||||
chan[5].keyOff=true;
|
||||
}
|
||||
immWrite(i,pendingWrites[i]&0xff);
|
||||
oldWrites[i]=pendingWrites[i];
|
||||
}
|
||||
|
@ -586,7 +599,7 @@ int DivPlatformGenesis::dispatch(DivCommand c) {
|
|||
}
|
||||
}
|
||||
if (c.chan>=5 && chan[c.chan].dacMode) {
|
||||
if (skipRegisterWrites) break;
|
||||
//if (skipRegisterWrites) break;
|
||||
if (ins->type==DIV_INS_AMIGA) { // Furnace mode
|
||||
if (c.value!=DIV_NOTE_NULL) chan[c.chan].dacSample=ins->amiga.getSample(c.value);
|
||||
if (chan[c.chan].dacSample<0 || chan[c.chan].dacSample>=parent->song.sampleLen) {
|
||||
|
@ -1117,14 +1130,20 @@ void DivPlatformGenesis::forceIns() {
|
|||
rWrite(chanOffs[i]+ADDR_FB_ALG,(chan[i].state.alg&7)|(chan[i].state.fb<<3));
|
||||
rWrite(chanOffs[i]+ADDR_LRAF,(IS_REALLY_MUTED(i)?0:(chan[i].pan<<6))|(chan[i].state.fms&7)|((chan[i].state.ams&3)<<4));
|
||||
if (chan[i].active) {
|
||||
chan[i].keyOn=true;
|
||||
chan[i].freqChanged=true;
|
||||
if (i<5 || !chan[i].dacMode) {
|
||||
chan[i].keyOn=true;
|
||||
chan[i].freqChanged=true;
|
||||
}
|
||||
}
|
||||
}
|
||||
immWrite(0x2b,0x00);
|
||||
//rWrite(0x2a,0x00);
|
||||
if (chan[5].dacMode) {
|
||||
rWrite(0x2b,0x80);
|
||||
chan[5].dacSample=-1;
|
||||
chan[6].dacSample=-1;
|
||||
}
|
||||
immWrite(0x22,lfoValue);
|
||||
flushFirst=true;
|
||||
}
|
||||
|
||||
void DivPlatformGenesis::toggleRegisterDump(bool enable) {
|
||||
|
@ -1151,6 +1170,10 @@ int DivPlatformGenesis::getRegisterPoolSize() {
|
|||
return 512;
|
||||
}
|
||||
|
||||
float DivPlatformGenesis::getPostAmp() {
|
||||
return 2.0f;
|
||||
}
|
||||
|
||||
void DivPlatformGenesis::reset() {
|
||||
while (!writes.empty()) writes.pop_front();
|
||||
memset(regPool,0,512);
|
||||
|
@ -1178,6 +1201,7 @@ void DivPlatformGenesis::reset() {
|
|||
lfoValue=8;
|
||||
softPCMTimer=0;
|
||||
extMode=false;
|
||||
flushFirst=false;
|
||||
|
||||
if (softPCM) {
|
||||
chan[5].dacMode=true;
|
||||
|
@ -1280,6 +1304,7 @@ int DivPlatformGenesis::init(DivEngine* p, int channels, int sugRate, const DivC
|
|||
dumpWrites=false;
|
||||
ladder=false;
|
||||
skipRegisterWrites=false;
|
||||
flushFirst=false;
|
||||
for (int i=0; i<10; i++) {
|
||||
isMuted[i]=false;
|
||||
oscBuf[i]=new DivDispatchOscBuffer;
|
||||
|
|
|
@ -114,6 +114,7 @@ class DivPlatformGenesis: public DivPlatformOPN {
|
|||
void setYMFM(bool use);
|
||||
bool keyOffAffectsArp(int ch);
|
||||
bool keyOffAffectsPorta(int ch);
|
||||
float getPostAmp();
|
||||
void toggleRegisterDump(bool enable);
|
||||
void setFlags(const DivConfig& flags);
|
||||
void notifyInsChange(int ins);
|
||||
|
|
|
@ -677,6 +677,8 @@ void DivPlatformGenesisExt::forceIns() {
|
|||
}
|
||||
}
|
||||
if (chan[5].dacMode) {
|
||||
chan[5].dacSample=-1;
|
||||
chan[6].dacSample=-1;
|
||||
rWrite(0x2b,0x80);
|
||||
}
|
||||
immWrite(0x22,lfoValue);
|
||||
|
|
|
@ -958,6 +958,10 @@ void DivPlatformOPLL::setYMFM(bool use) {
|
|||
useYMFM=use;
|
||||
}
|
||||
|
||||
float DivPlatformOPLL::getPostAmp() {
|
||||
return 1.5f;
|
||||
}
|
||||
|
||||
void DivPlatformOPLL::setFlags(const DivConfig& flags) {
|
||||
int clockSel=flags.getInt("clockSel",0);
|
||||
if (clockSel==3) {
|
||||
|
|
|
@ -95,6 +95,7 @@ class DivPlatformOPLL: public DivDispatch {
|
|||
void setYMFM(bool use);
|
||||
bool keyOffAffectsArp(int ch);
|
||||
bool keyOffAffectsPorta(int ch);
|
||||
float getPostAmp();
|
||||
void toggleRegisterDump(bool enable);
|
||||
void setVRC7(bool vrc);
|
||||
void setProperDrums(bool pd);
|
||||
|
|
|
@ -39,6 +39,10 @@ const char** DivPlatformSMS::getRegisterSheet() {
|
|||
return stereo?regCheatSheetGG:regCheatSheetSN;
|
||||
}
|
||||
|
||||
float DivPlatformSMS::getPostAmp() {
|
||||
return 1.5f;
|
||||
}
|
||||
|
||||
void DivPlatformSMS::acquire_nuked(short** buf, size_t len) {
|
||||
int oL=0;
|
||||
int oR=0;
|
||||
|
|
|
@ -81,6 +81,7 @@ class DivPlatformSMS: public DivDispatch {
|
|||
int getOutputCount();
|
||||
bool keyOffAffectsArp(int ch);
|
||||
bool keyOffAffectsPorta(int ch);
|
||||
float getPostAmp();
|
||||
int getPortaFloor(int ch);
|
||||
void setFlags(const DivConfig& flags);
|
||||
void notifyInsDeletion(void* ins);
|
||||
|
|
|
@ -135,7 +135,7 @@ void DivPlatformTIA::tick(bool sysTick) {
|
|||
int bf=chan[i].baseFreq;
|
||||
if (!parent->song.oldArpStrategy) {
|
||||
if (!chan[i].fixedArp) {
|
||||
bf+=chan[i].baseFreq+chan[i].arpOff;
|
||||
bf+=chan[i].arpOff;
|
||||
}
|
||||
}
|
||||
chan[i].freq=dealWithFreq(chan[i].shape,bf,chan[i].pitch)+chan[i].pitch2;
|
||||
|
|
|
@ -903,6 +903,10 @@ bool DivPlatformX1_010::keyOffAffectsArp(int ch) {
|
|||
return true;
|
||||
}
|
||||
|
||||
float DivPlatformX1_010::getPostAmp() {
|
||||
return 4.0f;
|
||||
}
|
||||
|
||||
void DivPlatformX1_010::notifyWaveChange(int wave) {
|
||||
for (int i=0; i<16; i++) {
|
||||
if (chan[i].wave==wave) {
|
||||
|
|
|
@ -140,6 +140,7 @@ class DivPlatformX1_010: public DivDispatch, public vgsound_emu_mem_intf {
|
|||
void muteChannel(int ch, bool mute);
|
||||
int getOutputCount();
|
||||
bool keyOffAffectsArp(int ch);
|
||||
float getPostAmp();
|
||||
void setFlags(const DivConfig& flags);
|
||||
void notifyWaveChange(int wave);
|
||||
void notifyInsDeletion(void* ins);
|
||||
|
|
|
@ -545,6 +545,10 @@ void DivPlatformYM2608::tick(bool sysTick) {
|
|||
chan[i].state.ams=chan[i].std.ams.val;
|
||||
rWrite(chanOffs[i]+ADDR_LRAF,(isMuted[i]?0:(chan[i].pan<<6))|(chan[i].state.fms&7)|((chan[i].state.ams&3)<<4));
|
||||
}
|
||||
if (chan[i].std.ex3.had) {
|
||||
lfoValue=(chan[i].std.ex3.val>7)?0:(8|(chan[i].std.ex3.val&7));
|
||||
rWrite(0x22,lfoValue);
|
||||
}
|
||||
if (chan[i].std.ex4.had && chan[i].active) {
|
||||
chan[i].opMask=chan[i].std.ex4.val&15;
|
||||
chan[i].opMaskChanged=true;
|
||||
|
|
|
@ -478,6 +478,10 @@ void DivPlatformYM2610::tick(bool sysTick) {
|
|||
chan[i].state.ams=chan[i].std.ams.val;
|
||||
rWrite(chanOffs[i]+ADDR_LRAF,(isMuted[i]?0:(chan[i].pan<<6))|(chan[i].state.fms&7)|((chan[i].state.ams&3)<<4));
|
||||
}
|
||||
if (chan[i].std.ex3.had) {
|
||||
lfoValue=(chan[i].std.ex3.val>7)?0:(8|(chan[i].std.ex3.val&7));
|
||||
rWrite(0x22,lfoValue);
|
||||
}
|
||||
if (chan[i].std.ex4.had && chan[i].active) {
|
||||
chan[i].opMask=chan[i].std.ex4.val&15;
|
||||
chan[i].opMaskChanged=true;
|
||||
|
|
|
@ -545,6 +545,10 @@ void DivPlatformYM2610B::tick(bool sysTick) {
|
|||
chan[i].state.ams=chan[i].std.ams.val;
|
||||
rWrite(chanOffs[i]+ADDR_LRAF,(isMuted[i]?0:(chan[i].pan<<6))|(chan[i].state.fms&7)|((chan[i].state.ams&3)<<4));
|
||||
}
|
||||
if (chan[i].std.ex3.had) {
|
||||
lfoValue=(chan[i].std.ex3.val>7)?0:(8|(chan[i].std.ex3.val&7));
|
||||
rWrite(0x22,lfoValue);
|
||||
}
|
||||
if (chan[i].std.ex4.had && chan[i].active) {
|
||||
chan[i].opMask=chan[i].std.ex4.val&15;
|
||||
chan[i].opMaskChanged=true;
|
||||
|
|
|
@ -896,7 +896,7 @@ void DivEngine::processRow(int i, bool afterDelay) {
|
|||
chan[i].vibratoPos=0;
|
||||
}
|
||||
dispatchCmd(DivCommand(DIV_CMD_PITCH,i,chan[i].pitch+(((chan[i].vibratoDepth*vibTable[chan[i].vibratoPos]*chan[i].vibratoFine)>>4)/15)));
|
||||
if (chan[i].legato) {
|
||||
if (chan[i].legato && (!chan[i].inPorta || song.brokenPortaLegato)) {
|
||||
dispatchCmd(DivCommand(DIV_CMD_LEGATO,i,chan[i].note));
|
||||
dispatchCmd(DivCommand(DIV_CMD_HINT_LEGATO,i,chan[i].note));
|
||||
} else {
|
||||
|
|
|
@ -827,18 +827,15 @@ bool DivSample::resampleBlep(double r) {
|
|||
unsigned int posInt=0;
|
||||
double factor=r/(double)rate;
|
||||
float* sincITable=DivFilterTables::getSincIntegralTable();
|
||||
float s[16];
|
||||
|
||||
memset(s,0,16*sizeof(float));
|
||||
float* floatData=new float[finalCount];
|
||||
memset(floatData,0,finalCount*sizeof(float));
|
||||
|
||||
if (depth==DIV_SAMPLE_DEPTH_16BIT) {
|
||||
memset(data16,0,finalCount*sizeof(short));
|
||||
for (int i=0; i<finalCount; i++) {
|
||||
if (posInt<samples) {
|
||||
int result=data16[i]+oldData16[posInt];
|
||||
if (result<-32768) result=-32768;
|
||||
if (result>32767) result=32767;
|
||||
data16[i]=result;
|
||||
data16[i]=oldData16[posInt];
|
||||
}
|
||||
|
||||
posFrac+=1.0;
|
||||
|
@ -853,28 +850,25 @@ bool DivSample::resampleBlep(double r) {
|
|||
|
||||
for (int j=0; j<8; j++) {
|
||||
if (i-j>0) {
|
||||
float result=data16[i-j]+t1[j]*-delta;
|
||||
if (result<-32768) result=-32768;
|
||||
if (result>32767) result=32767;
|
||||
data16[i-j]=result;
|
||||
floatData[i-j]+=t1[j]*-delta;
|
||||
}
|
||||
if (i+j+1<finalCount) {
|
||||
float result=data16[i+j+1]+t2[j]*delta;
|
||||
if (result<-32768) result=-32768;
|
||||
if (result>32767) result=32767;
|
||||
data16[i+j+1]=result;
|
||||
floatData[i+j+1]+=t2[j]*delta;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i=0; i<finalCount; i++) {
|
||||
float result=floatData[i]+data16[i];
|
||||
if (result<-32768) result=-32768;
|
||||
if (result>32767) result=32767;
|
||||
data16[i]=round(result);
|
||||
}
|
||||
} else if (depth==DIV_SAMPLE_DEPTH_8BIT) {
|
||||
memset(data8,0,finalCount);
|
||||
for (int i=0; i<finalCount; i++) {
|
||||
if (posInt<samples) {
|
||||
int result=data8[i]+oldData8[posInt];
|
||||
if (result<-128) result=-128;
|
||||
if (result>127) result=127;
|
||||
data8[i]=result;
|
||||
data8[i]=oldData8[posInt];
|
||||
}
|
||||
|
||||
posFrac+=1.0;
|
||||
|
@ -889,21 +883,22 @@ bool DivSample::resampleBlep(double r) {
|
|||
|
||||
for (int j=0; j<8; j++) {
|
||||
if (i-j>0) {
|
||||
float result=data8[i-j]+t1[j]*-delta;
|
||||
if (result<-128) result=-128;
|
||||
if (result>127) result=127;
|
||||
data8[i-j]=result;
|
||||
floatData[i-j]+=t1[j]*-delta;
|
||||
}
|
||||
if (i+j+1<finalCount) {
|
||||
float result=data8[i+j+1]+t2[j]*delta;
|
||||
if (result<-128) result=-128;
|
||||
if (result>127) result=127;
|
||||
data8[i+j+1]=result;
|
||||
floatData[i+j+1]+=t2[j]*delta;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i=0; i<finalCount; i++) {
|
||||
float result=floatData[i]+data16[i];
|
||||
if (result<-128) result=-128;
|
||||
if (result>127) result=127;
|
||||
data16[i]=round(result);
|
||||
}
|
||||
}
|
||||
delete[] floatData;
|
||||
|
||||
RESAMPLE_END;
|
||||
return true;
|
||||
|
|
|
@ -330,6 +330,7 @@ struct DivSong {
|
|||
bool autoSystem;
|
||||
bool oldArpStrategy;
|
||||
bool patchbayAuto;
|
||||
bool brokenPortaLegato;
|
||||
|
||||
std::vector<DivInstrument*> ins;
|
||||
std::vector<DivWavetable*> wave;
|
||||
|
@ -439,7 +440,8 @@ struct DivSong {
|
|||
disableSampleMacro(false),
|
||||
autoSystem(true),
|
||||
oldArpStrategy(false),
|
||||
patchbayAuto(true) {
|
||||
patchbayAuto(true),
|
||||
brokenPortaLegato(false) {
|
||||
for (int i=0; i<DIV_MAX_CHIPS; i++) {
|
||||
system[i]=DIV_SYSTEM_NULL;
|
||||
systemVol[i]=1.0;
|
||||
|
|
|
@ -1046,7 +1046,7 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p
|
|||
case DIV_SYSTEM_SMS:
|
||||
if (!hasSN) {
|
||||
hasSN=disCont[i].dispatch->chipClock;
|
||||
CHIP_VOL(0,2.0);
|
||||
CHIP_VOL(0,4.0);
|
||||
willExport[i]=true;
|
||||
switch (song.systemFlags[i].getInt("chipType",0)) {
|
||||
case 1: // real SN
|
||||
|
@ -1065,7 +1065,7 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p
|
|||
} else if (!(hasSN&0x40000000)) {
|
||||
isSecond[i]=true;
|
||||
willExport[i]=true;
|
||||
CHIP_VOL_SECOND(0,2.0);
|
||||
CHIP_VOL_SECOND(0,4.0);
|
||||
hasSN|=0x40000000;
|
||||
howManyChips++;
|
||||
}
|
||||
|
@ -1130,12 +1130,12 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p
|
|||
case DIV_SYSTEM_X1_010:
|
||||
if (!hasX1) {
|
||||
hasX1=disCont[i].dispatch->chipClock;
|
||||
CHIP_VOL(38,0.5);
|
||||
CHIP_VOL(38,2.0);
|
||||
willExport[i]=true;
|
||||
writeX1010[0]=disCont[i].dispatch;
|
||||
} else if (!(hasX1&0x40000000)) {
|
||||
isSecond[i]=true;
|
||||
CHIP_VOL_SECOND(38,0.5);
|
||||
CHIP_VOL_SECOND(38,2.0);
|
||||
willExport[i]=true;
|
||||
writeX1010[1]=disCont[i].dispatch;
|
||||
hasX1|=0x40000000;
|
||||
|
@ -1232,12 +1232,12 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p
|
|||
case DIV_SYSTEM_YM2612_DUALPCM_EXT:
|
||||
if (!hasOPN2) {
|
||||
hasOPN2=disCont[i].dispatch->chipClock;
|
||||
CHIP_VOL(2,0.8);
|
||||
CHIP_VOL(2,1.6);
|
||||
willExport[i]=true;
|
||||
writeDACSamples=true;
|
||||
} else if (!(hasOPN2&0x40000000)) {
|
||||
isSecond[i]=true;
|
||||
CHIP_VOL_SECOND(2,0.8);
|
||||
CHIP_VOL_SECOND(2,1.6);
|
||||
willExport[i]=true;
|
||||
hasOPN2|=0x40000000;
|
||||
howManyChips++;
|
||||
|
@ -1296,11 +1296,11 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p
|
|||
case DIV_SYSTEM_VRC7:
|
||||
if (!hasOPLL) {
|
||||
hasOPLL=disCont[i].dispatch->chipClock;
|
||||
CHIP_VOL(1,1.6);
|
||||
CHIP_VOL(1,3.2);
|
||||
willExport[i]=true;
|
||||
} else if (!(hasOPLL&0x40000000)) {
|
||||
isSecond[i]=true;
|
||||
CHIP_VOL_SECOND(1,1.6);
|
||||
CHIP_VOL_SECOND(1,3.2);
|
||||
willExport[i]=true;
|
||||
hasOPLL|=0x40000000;
|
||||
howManyChips++;
|
||||
|
|
|
@ -69,6 +69,7 @@ const char* aboutLine[]={
|
|||
"brickblock369",
|
||||
"Burnt Fishy",
|
||||
"CaptainMalware",
|
||||
"Clingojam",
|
||||
"DeMOSic",
|
||||
"DevEd",
|
||||
"Dippy",
|
||||
|
|
|
@ -214,7 +214,7 @@ void FurnaceGUI::drawCompatFlags() {
|
|||
e->song.delayBehavior=2;
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("no checks (like FamiTracker)");
|
||||
ImGui::SetTooltip("no checks");
|
||||
}
|
||||
|
||||
ImGui::Text("Simultaneous jump (0B+0D) treatment:");
|
||||
|
@ -293,6 +293,10 @@ void FurnaceGUI::drawCompatFlags() {
|
|||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("behavior changed in 0.6pre2");
|
||||
}
|
||||
ImGui::Checkbox("Broken portamento during legato",&e->song.brokenPortaLegato);
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("behavior changed in 0.6pre4");
|
||||
}
|
||||
}
|
||||
if (ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows)) curWindow=GUI_WINDOW_COMPAT_FLAGS;
|
||||
ImGui::End();
|
||||
|
|
|
@ -163,7 +163,7 @@ void FurnaceGUI::doAction(int what) {
|
|||
case GUI_ACTION_TX81Z_REQUEST: {
|
||||
TAMidiMessage msg;
|
||||
msg.type=TA_MIDI_SYSEX;
|
||||
msg.sysExData.reset(new unsigned char[15]);
|
||||
msg.sysExData.reset(new unsigned char[15],std::default_delete<unsigned char[]>());
|
||||
msg.sysExLen=15;
|
||||
memcpy(msg.sysExData.get(),avRequest,15);
|
||||
if (!e->sendMidiMessage(msg)) {
|
||||
|
|
|
@ -506,7 +506,9 @@ void FurnaceGUI::drawMobileControls() {
|
|||
ImGui::SameLine();
|
||||
ImGui::Button("Legacy .dmf");
|
||||
ImGui::SameLine();
|
||||
ImGui::Button("Export Audio");
|
||||
if (ImGui::Button("Export Audio")) {
|
||||
openFileDialog(GUI_FILE_EXPORT_AUDIO_ONE);
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Export VGM")) {
|
||||
openFileDialog(GUI_FILE_EXPORT_VGM);
|
||||
|
|
|
@ -3132,6 +3132,14 @@ bool FurnaceGUI::loop() {
|
|||
break;
|
||||
case SDL_DISPLAYEVENT: {
|
||||
switch (ev.display.event) {
|
||||
case SDL_DISPLAYEVENT_CONNECTED:
|
||||
logD("display %d connected!",ev.display.display);
|
||||
updateWindow=true;
|
||||
break;
|
||||
case SDL_DISPLAYEVENT_DISCONNECTED:
|
||||
logD("display %d disconnected!",ev.display.display);
|
||||
updateWindow=true;
|
||||
break;
|
||||
case SDL_DISPLAYEVENT_ORIENTATION:
|
||||
logD("display oriented to %d",ev.display.data1);
|
||||
updateWindow=true;
|
||||
|
|
|
@ -1295,6 +1295,7 @@ class FurnaceGUI {
|
|||
double exportFadeOut;
|
||||
int macroLayout;
|
||||
float doubleClickTime;
|
||||
int oneDigitEffects;
|
||||
unsigned int maxUndoSteps;
|
||||
String mainFontPath;
|
||||
String patFontPath;
|
||||
|
@ -1430,6 +1431,7 @@ class FurnaceGUI {
|
|||
exportFadeOut(0.0),
|
||||
macroLayout(0),
|
||||
doubleClickTime(0.3f),
|
||||
oneDigitEffects(0),
|
||||
maxUndoSteps(100),
|
||||
mainFontPath(""),
|
||||
patFontPath(""),
|
||||
|
|
|
@ -352,6 +352,10 @@ const int detuneUnmap[2][11]={
|
|||
{0, 0, 0, 3, 4, 5, 6, 7, 2, 1, 0}
|
||||
};
|
||||
|
||||
const int kslMap[4]={
|
||||
0, 2, 1, 3
|
||||
};
|
||||
|
||||
// do not change these!
|
||||
// anything other than a checkbox will look ugly!
|
||||
//
|
||||
|
@ -2778,7 +2782,11 @@ void FurnaceGUI::drawInsEdit() {
|
|||
if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) {
|
||||
P(CWVSliderScalar("##RS",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.rs,&_ZERO,&_THREE));
|
||||
} else {
|
||||
P(CWVSliderScalar("##KSL",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.ksl,&_ZERO,&_THREE));
|
||||
int ksl=ins->type==DIV_INS_OPLL?op.ksl:kslMap[op.ksl&3];
|
||||
if (CWVSliderInt("##KSL",ImVec2(20.0f*dpiScale,sliderHeight),&ksl,0,3)) {
|
||||
op.ksl=(ins->type==DIV_INS_OPLL?ksl:kslMap[ksl&3]);
|
||||
PARAMETER;
|
||||
}
|
||||
}
|
||||
|
||||
if (ins->type==DIV_INS_OPZ) {
|
||||
|
@ -3226,7 +3234,7 @@ void FurnaceGUI::drawInsEdit() {
|
|||
|
||||
break;
|
||||
case DIV_INS_OPL:
|
||||
case DIV_INS_OPL_DRUMS:
|
||||
case DIV_INS_OPL_DRUMS: {
|
||||
// waveform
|
||||
drawWaveform(op.ws&7,ins->type==DIV_INS_OPZ,ImVec2(waveWidth,waveHeight));
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
|
@ -3268,9 +3276,14 @@ void FurnaceGUI::drawInsEdit() {
|
|||
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_KSL));
|
||||
P(CWSliderScalar("##KSL",ImGuiDataType_U8,&op.ksl,&_ZERO,&_THREE,tempID)); rightClickable
|
||||
int ksl=kslMap[op.ksl&3];
|
||||
if (CWSliderInt("##KSL",&ksl,0,3,tempID)) {
|
||||
op.ksl=kslMap[ksl&3];
|
||||
PARAMETER;
|
||||
} rightClickable
|
||||
|
||||
break;
|
||||
}
|
||||
case DIV_INS_OPZ: {
|
||||
// waveform
|
||||
drawWaveform(op.ws&7,ins->type==DIV_INS_OPZ,ImVec2(waveWidth,waveHeight));
|
||||
|
@ -3613,7 +3626,11 @@ void FurnaceGUI::drawInsEdit() {
|
|||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%s",FM_NAME(FM_RS));
|
||||
} else {
|
||||
P(CWSliderScalar("##KSL",ImGuiDataType_U8,&op.ksl,&_ZERO,&_THREE)); rightClickable
|
||||
int ksl=ins->type==DIV_INS_OPLL?op.ksl:kslMap[op.ksl&3];
|
||||
if (CWSliderInt("##KSL",&ksl,0,3)) {
|
||||
op.ksl=(ins->type==DIV_INS_OPLL?ksl:kslMap[ksl&3]);
|
||||
PARAMETER;
|
||||
} rightClickable
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%s",FM_NAME(FM_KSL));
|
||||
}
|
||||
|
@ -3779,6 +3796,9 @@ void FurnaceGUI::drawInsEdit() {
|
|||
}
|
||||
}
|
||||
|
||||
if (ins->type==DIV_INS_FM) {
|
||||
macroList.push_back(FurnaceGUIMacroDesc("LFO Speed",&ins->std.ex3Macro,0,8,96,uiColors[GUI_COLOR_MACRO_OTHER]));
|
||||
}
|
||||
if (ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) {
|
||||
macroList.push_back(FurnaceGUIMacroDesc("AM Depth",&ins->std.ex1Macro,0,127,128,uiColors[GUI_COLOR_MACRO_OTHER]));
|
||||
macroList.push_back(FurnaceGUIMacroDesc("PM Depth",&ins->std.ex2Macro,0,127,128,uiColors[GUI_COLOR_MACRO_OTHER]));
|
||||
|
|
|
@ -287,10 +287,14 @@ inline void FurnaceGUI::patternRow(int i, bool isPlaying, float lineHeight, int
|
|||
if (pat->data[i][index]>0xff) {
|
||||
snprintf(id,63,"??##PE%d_%d_%d",k,i,j);
|
||||
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_PATTERN_EFFECT_INVALID]);
|
||||
} else {
|
||||
} else if (pat->data[i][index]>0x10 || settings.oneDigitEffects==0) {
|
||||
const unsigned char data=pat->data[i][index];
|
||||
snprintf(id,63,"%.2X##PE%d_%d_%d",data,k,i,j);
|
||||
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[fxColors[data]]);
|
||||
} else {
|
||||
const unsigned char data=pat->data[i][index];
|
||||
snprintf(id,63," %.1X##PE%d_%d_%d",data,k,i,j);
|
||||
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[fxColors[data]]);
|
||||
}
|
||||
}
|
||||
ImGui::SameLine(0.0f,0.0f);
|
||||
|
|
|
@ -1602,6 +1602,11 @@ void FurnaceGUI::drawSettings() {
|
|||
settings.germanNotation=germanNotationB;
|
||||
}
|
||||
|
||||
bool oneDigitEffectsB=settings.oneDigitEffects;
|
||||
if (ImGui::Checkbox("Single-digit effects for 00-0F",&oneDigitEffectsB)) {
|
||||
settings.oneDigitEffects=oneDigitEffectsB;
|
||||
}
|
||||
|
||||
bool centerPatternB=settings.centerPattern;
|
||||
if (ImGui::Checkbox("Center pattern view",¢erPatternB)) {
|
||||
settings.centerPattern=centerPatternB;
|
||||
|
@ -2565,6 +2570,7 @@ void FurnaceGUI::syncSettings() {
|
|||
settings.exportFadeOut=e->getConfDouble("exportFadeOut",0.0);
|
||||
settings.macroLayout=e->getConfInt("macroLayout",0);
|
||||
settings.doubleClickTime=e->getConfFloat("doubleClickTime",0.3f);
|
||||
settings.oneDigitEffects=e->getConfInt("oneDigitEffects",0);
|
||||
|
||||
clampSetting(settings.mainFontSize,2,96);
|
||||
clampSetting(settings.patFontSize,2,96);
|
||||
|
@ -2676,6 +2682,7 @@ void FurnaceGUI::syncSettings() {
|
|||
clampSetting(settings.persistFadeOut,0,1);
|
||||
clampSetting(settings.macroLayout,0,4);
|
||||
clampSetting(settings.doubleClickTime,0.02,1.0);
|
||||
clampSetting(settings.oneDigitEffects,0,1);
|
||||
|
||||
if (settings.exportLoops<0.0) settings.exportLoops=0.0;
|
||||
if (settings.exportFadeOut<0.0) settings.exportFadeOut=0.0;
|
||||
|
@ -2880,6 +2887,7 @@ void FurnaceGUI::commitSettings() {
|
|||
e->setConf("exportFadeOut",settings.exportFadeOut);
|
||||
e->setConf("macroLayout",settings.macroLayout);
|
||||
e->setConf("doubleClickTime",settings.doubleClickTime);
|
||||
e->setConf("oneDigitEffects",settings.oneDigitEffects);
|
||||
|
||||
// colors
|
||||
for (int i=0; i<GUI_COLOR_MAX; i++) {
|
||||
|
|
Loading…
Reference in a new issue