Merge branch 'master' of https://github.com/tildearrow/furnace into k053260

This commit is contained in:
cam900 2023-04-15 21:24:00 +09:00
commit e1dbc16d96
10 changed files with 229 additions and 75 deletions

View File

@ -2668,10 +2668,17 @@ void DivEngine::previewSampleNoLock(int sample, int note, int pStart, int pEnd)
if (rate<=0) rate=song.sample[sample]->centerRate; if (rate<=0) rate=song.sample[sample]->centerRate;
} }
if (rate<100) rate=100; if (rate<100) rate=100;
double rateOrig=rate;
sPreview.rateMul=1;
while (sPreview.rateMul<0x40000000 && rate<got.rate) {
sPreview.rateMul<<=1;
rate*=2.0;
}
blip_set_rates(samp_bb,rate,got.rate); blip_set_rates(samp_bb,rate,got.rate);
samp_prevSample=0; samp_prevSample=0;
sPreview.rate=rate; sPreview.rate=rateOrig;
sPreview.pos=(sPreview.pBegin>=0)?sPreview.pBegin:0; sPreview.pos=(sPreview.pBegin>=0)?sPreview.pBegin:0;
sPreview.posSub=0;
sPreview.sample=sample; sPreview.sample=sample;
sPreview.wave=-1; sPreview.wave=-1;
sPreview.dir=false; sPreview.dir=false;
@ -2696,10 +2703,17 @@ void DivEngine::previewWaveNoLock(int wave, int note) {
blip_clear(samp_bb); blip_clear(samp_bb);
double rate=song.wave[wave]->len*((song.tuning*0.0625)*pow(2.0,(double)(note+3)/12.0)); double rate=song.wave[wave]->len*((song.tuning*0.0625)*pow(2.0,(double)(note+3)/12.0));
if (rate<100) rate=100; if (rate<100) rate=100;
double rateOrig=rate;
sPreview.rateMul=1;
while (sPreview.rateMul<0x40000000 && rate<got.rate) {
sPreview.rateMul<<=1;
rate*=2.0;
}
blip_set_rates(samp_bb,rate,got.rate); blip_set_rates(samp_bb,rate,got.rate);
samp_prevSample=0; samp_prevSample=0;
sPreview.rate=rate; sPreview.rate=rateOrig;
sPreview.pos=0; sPreview.pos=0;
sPreview.posSub=0;
sPreview.sample=-1; sPreview.sample=-1;
sPreview.wave=wave; sPreview.wave=wave;
sPreview.dir=false; sPreview.dir=false;

View File

@ -53,8 +53,8 @@
#define EXTERN_BUSY_BEGIN_SOFT e->softLocked=true; e->isBusy.lock(); #define EXTERN_BUSY_BEGIN_SOFT e->softLocked=true; e->isBusy.lock();
#define EXTERN_BUSY_END e->isBusy.unlock(); e->softLocked=false; #define EXTERN_BUSY_END e->isBusy.unlock(); e->softLocked=false;
#define DIV_VERSION "dev152" #define DIV_VERSION "dev153"
#define DIV_ENGINE_VERSION 152 #define DIV_ENGINE_VERSION 153
// for imports // for imports
#define DIV_VERSION_MOD 0xff01 #define DIV_VERSION_MOD 0xff01
#define DIV_VERSION_FC 0xff02 #define DIV_VERSION_FC 0xff02
@ -414,6 +414,7 @@ class DivEngine {
int wave; int wave;
int pos; int pos;
int pBegin, pEnd; int pBegin, pEnd;
int rateMul, posSub;
bool dir; bool dir;
SamplePreview(): SamplePreview():
rate(0.0), rate(0.0),
@ -422,6 +423,8 @@ class DivEngine {
pos(0), pos(0),
pBegin(-1), pBegin(-1),
pEnd(-1), pEnd(-1),
rateMul(1),
posSub(0),
dir(false) {} dir(false) {}
} sPreview; } sPreview;

View File

@ -2715,6 +2715,15 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
} }
} }
// SrgaPCM slide compat
if (ds.version<153) {
for (int i=0; i<ds.systemLen; i++) {
if (ds.system[i]==DIV_SYSTEM_SEGAPCM || ds.system[i]==DIV_SYSTEM_SEGAPCM_COMPAT) {
ds.systemFlags[i].set("oldSlides",true);
}
}
}
if (active) quitDispatch(); if (active) quitDispatch();
BUSY_BEGIN_SOFT; BUSY_BEGIN_SOFT;
saveLock.lock(); saveLock.lock();

View File

@ -72,7 +72,7 @@ void DivPlatformSegaPCM::tick(bool sysTick) {
chan[i].handleArp(); chan[i].handleArp();
} else if (chan[i].std.arp.had) { } else if (chan[i].std.arp.had) {
if (!chan[i].inPorta) { if (!chan[i].inPorta) {
chan[i].baseFreq=(parent->calcArp(chan[i].note,chan[i].std.arp.val)<<6); chan[i].baseFreq=(parent->calcArp(chan[i].note,chan[i].std.arp.val)<<7);
} }
chan[i].freqChanged=true; chan[i].freqChanged=true;
} }
@ -106,21 +106,22 @@ void DivPlatformSegaPCM::tick(bool sysTick) {
} }
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) { if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
chan[i].freq=chan[i].baseFreq+(chan[i].pitch>>1)-64; chan[i].freq=chan[i].baseFreq+(chan[i].pitch)-128+(oldSlides?0:chan[i].pitch2);
if (!parent->song.oldArpStrategy) { if (!parent->song.oldArpStrategy) {
if (chan[i].fixedArp) { if (chan[i].fixedArp) {
chan[i].freq=(chan[i].baseNoteOverride<<6)+(chan[i].pitch>>1)-64+chan[i].pitch2; chan[i].freq=(chan[i].baseNoteOverride<<7)+chan[i].pitch-128+(chan[i].pitch2<<(oldSlides?1:0));
} else { } else {
chan[i].freq+=chan[i].arpOff<<6; chan[i].freq+=chan[i].arpOff<<7;
} }
} }
if (oldSlides) chan[i].freq&=~1;
if (chan[i].furnacePCM) { if (chan[i].furnacePCM) {
double off=1.0; double off=1.0;
if (chan[i].pcm.sample>=0 && chan[i].pcm.sample<parent->song.sampleLen) { if (chan[i].pcm.sample>=0 && chan[i].pcm.sample<parent->song.sampleLen) {
DivSample* s=parent->getSample(chan[i].pcm.sample); DivSample* s=parent->getSample(chan[i].pcm.sample);
off=(double)s->centerRate/8363.0; off=(double)s->centerRate/8363.0;
} }
chan[i].pcm.freq=MIN(255,(15625+(off*parent->song.tuning*pow(2.0,double(chan[i].freq+256)/(64.0*12.0)))*255)/31250)+chan[i].pitch2; chan[i].pcm.freq=MIN(255,(15625+(off*parent->song.tuning*pow(2.0,double(chan[i].freq+512)/(128.0*12.0)))*255)/31250)+(oldSlides?chan[i].pitch2:0);
rWrite(7+(i<<3),chan[i].pcm.freq); rWrite(7+(i<<3),chan[i].pcm.freq);
} }
chan[i].freqChanged=false; chan[i].freqChanged=false;
@ -201,7 +202,7 @@ int DivPlatformSegaPCM::dispatch(DivCommand c) {
} }
if (c.value!=DIV_NOTE_NULL) { if (c.value!=DIV_NOTE_NULL) {
chan[c.chan].note=c.value; chan[c.chan].note=c.value;
chan[c.chan].baseFreq=(c.value<<6); chan[c.chan].baseFreq=(c.value<<7);
chan[c.chan].freqChanged=true; chan[c.chan].freqChanged=true;
} }
chan[c.chan].furnacePCM=true; chan[c.chan].furnacePCM=true;
@ -289,17 +290,18 @@ int DivPlatformSegaPCM::dispatch(DivCommand c) {
break; break;
} }
case DIV_CMD_NOTE_PORTA: { case DIV_CMD_NOTE_PORTA: {
int destFreq=(c.value2<<6); int destFreq=(c.value2<<7);
int newFreq; int newFreq;
int mul=(oldSlides || parent->song.linearPitch!=2)?8:1;
bool return2=false; bool return2=false;
if (destFreq>chan[c.chan].baseFreq) { if (destFreq>chan[c.chan].baseFreq) {
newFreq=chan[c.chan].baseFreq+c.value*4; newFreq=chan[c.chan].baseFreq+c.value*mul;
if (newFreq>=destFreq) { if (newFreq>=destFreq) {
newFreq=destFreq; newFreq=destFreq;
return2=true; return2=true;
} }
} else { } else {
newFreq=chan[c.chan].baseFreq-c.value*4; newFreq=chan[c.chan].baseFreq-c.value*mul;
if (newFreq<=destFreq) { if (newFreq<=destFreq) {
newFreq=destFreq; newFreq=destFreq;
return2=true; return2=true;
@ -314,7 +316,7 @@ int DivPlatformSegaPCM::dispatch(DivCommand c) {
break; break;
} }
case DIV_CMD_LEGATO: { case DIV_CMD_LEGATO: {
chan[c.chan].baseFreq=(c.value<<6); chan[c.chan].baseFreq=(c.value<<7);
chan[c.chan].freqChanged=true; chan[c.chan].freqChanged=true;
break; break;
} }
@ -337,7 +339,7 @@ int DivPlatformSegaPCM::dispatch(DivCommand c) {
return 127; return 127;
break; break;
case DIV_CMD_PRE_PORTA: case DIV_CMD_PRE_PORTA:
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will && !NEW_ARP_STRAT) chan[c.chan].baseFreq=(chan[c.chan].note<<6); if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will && !NEW_ARP_STRAT) chan[c.chan].baseFreq=(chan[c.chan].note<<7);
chan[c.chan].inPorta=c.value; chan[c.chan].inPorta=c.value;
break; break;
case DIV_CMD_PRE_NOTE: case DIV_CMD_PRE_NOTE:
@ -504,6 +506,8 @@ void DivPlatformSegaPCM::setFlags(const DivConfig& flags) {
for (int i=0; i<16; i++) { for (int i=0; i<16; i++) {
oscBuf[i]->rate=rate; oscBuf[i]->rate=rate;
} }
oldSlides=flags.getBool("oldSlides",false);
} }
int DivPlatformSegaPCM::getOutputCount() { int DivPlatformSegaPCM::getOutputCount() {

View File

@ -65,6 +65,7 @@ class DivPlatformSegaPCM: public DivDispatch {
segapcm_device pcm; segapcm_device pcm;
int delay; int delay;
int pcmL, pcmR, pcmCycles; int pcmL, pcmR, pcmCycles;
bool oldSlides;
unsigned char sampleBank; unsigned char sampleBank;
unsigned char lastBusy; unsigned char lastBusy;

View File

@ -1541,10 +1541,13 @@ void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsi
samp_temp=0; samp_temp=0;
} else { } else {
samp_temp=s->data16[sPreview.pos]; samp_temp=s->data16[sPreview.pos];
if (sPreview.dir) { if (--sPreview.posSub<=0) {
sPreview.pos--; sPreview.posSub=sPreview.rateMul;
} else { if (sPreview.dir) {
sPreview.pos++; sPreview.pos--;
} else {
sPreview.pos++;
}
} }
} }
blip_add_delta(samp_bb,i,samp_temp-samp_prevSample); blip_add_delta(samp_bb,i,samp_temp-samp_prevSample);
@ -1649,8 +1652,11 @@ void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsi
} else { } else {
samp_temp=((MIN(wave->data[sPreview.pos],wave->max)<<14)/wave->max)-8192; samp_temp=((MIN(wave->data[sPreview.pos],wave->max)<<14)/wave->max)-8192;
} }
if (++sPreview.pos>=wave->len) { if (--sPreview.posSub<=0) {
sPreview.pos=0; sPreview.posSub=sPreview.rateMul;
if (++sPreview.pos>=wave->len) {
sPreview.pos=0;
}
} }
blip_add_delta(samp_bb,i,samp_temp-samp_prevSample); blip_add_delta(samp_bb,i,samp_temp-samp_prevSample);
samp_prevSample=samp_temp; samp_prevSample=samp_temp;

View File

@ -540,9 +540,23 @@ void FurnaceGUI::drawDebug() {
} }
if (ImGui::TreeNode("Performance")) { if (ImGui::TreeNode("Performance")) {
double perfFreq=SDL_GetPerformanceFrequency()/1000000.0; double perfFreq=SDL_GetPerformanceFrequency()/1000000.0;
int lastProcTime=(int)e->processTime/1000;
TAAudioDesc& audioGot=e->getAudioDescGot();
ImGui::Text("video frame: %.0fµs",ImGui::GetIO().DeltaTime*1000000.0);
ImGui::Text("audio frame: %.0fµs",1000000.0*(double)audioGot.bufsize/(double)audioGot.rate);
ImGui::Separator();
ImGui::Text("audio: %dµs",lastProcTime);
ImGui::Text("render: %.0fµs",(double)renderTimeDelta/perfFreq); ImGui::Text("render: %.0fµs",(double)renderTimeDelta/perfFreq);
ImGui::Text("layout: %.0fµs",(double)layoutTimeDelta/perfFreq); ImGui::Text("layout: %.0fµs",(double)layoutTimeDelta/perfFreq);
ImGui::Text("event: %.0fµs",(double)eventTimeDelta/perfFreq); ImGui::Text("event: %.0fµs",(double)eventTimeDelta/perfFreq);
ImGui::Separator();
ImGui::Text("details:");
for (int i=0; i<perfMetricsLastLen; i++) {
ImGui::Text("%s: %.0fµs",perfMetricsLast[i].name,(double)perfMetricsLast[i].elapsed/perfFreq);
}
ImGui::TreePop(); ImGui::TreePop();
} }
if (ImGui::TreeNode("Settings")) { if (ImGui::TreeNode("Settings")) {

View File

@ -3271,7 +3271,62 @@ bool FurnaceGUI::detectOutOfBoundsWindow() {
return false; return false;
} }
#define DECLARE_METRIC(_n) \
int __perfM##_n;
#define MEASURE_BEGIN(_n) \
__perfM##_n=SDL_GetPerformanceCounter();
#define MEASURE_END(_n) \
if (perfMetricsLen<64) { \
perfMetrics[perfMetricsLen++]=FurnaceGUIPerfMetric(#_n,SDL_GetPerformanceCounter()-__perfM##_n); \
}
#define MEASURE(_n,_x) \
MEASURE_BEGIN(_n) \
_x; \
MEASURE_END(_n)
bool FurnaceGUI::loop() { bool FurnaceGUI::loop() {
DECLARE_METRIC(calcChanOsc)
DECLARE_METRIC(mobileControls)
DECLARE_METRIC(mobileOrderSel)
DECLARE_METRIC(subSongs)
DECLARE_METRIC(findReplace)
DECLARE_METRIC(spoiler)
DECLARE_METRIC(pattern)
DECLARE_METRIC(editControls)
DECLARE_METRIC(speed)
DECLARE_METRIC(grooves)
DECLARE_METRIC(songInfo)
DECLARE_METRIC(orders)
DECLARE_METRIC(intro)
DECLARE_METRIC(sampleList)
DECLARE_METRIC(sampleEdit)
DECLARE_METRIC(waveList)
DECLARE_METRIC(waveEdit)
DECLARE_METRIC(insList)
DECLARE_METRIC(insEdit)
DECLARE_METRIC(mixer)
DECLARE_METRIC(readOsc)
DECLARE_METRIC(osc)
DECLARE_METRIC(chanOsc)
DECLARE_METRIC(volMeter)
DECLARE_METRIC(settings)
DECLARE_METRIC(debug)
DECLARE_METRIC(stats)
DECLARE_METRIC(compatFlags)
DECLARE_METRIC(piano)
DECLARE_METRIC(notes)
DECLARE_METRIC(channels)
DECLARE_METRIC(patManager)
DECLARE_METRIC(sysManager)
DECLARE_METRIC(clock)
DECLARE_METRIC(regView)
DECLARE_METRIC(log)
DECLARE_METRIC(effectList)
DECLARE_METRIC(popup)
#ifdef IS_MOBILE #ifdef IS_MOBILE
bool doThreadedInput=true; bool doThreadedInput=true;
#else #else
@ -3293,6 +3348,11 @@ bool FurnaceGUI::loop() {
drawHalt=0; drawHalt=0;
if (settings.powerSave) SDL_WaitEventTimeout(NULL,500); if (settings.powerSave) SDL_WaitEventTimeout(NULL,500);
} }
memcpy(perfMetricsLast,perfMetrics,64*sizeof(FurnaceGUIPerfMetric));
perfMetricsLastLen=perfMetricsLen;
perfMetricsLen=0;
eventTimeBegin=SDL_GetPerformanceCounter(); eventTimeBegin=SDL_GetPerformanceCounter();
bool updateWindow=false; bool updateWindow=false;
if (injectBackUp) { if (injectBackUp) {
@ -4181,83 +4241,85 @@ bool FurnaceGUI::loop() {
ImGui::EndMainMenuBar(); ImGui::EndMainMenuBar();
} }
calcChanOsc(); MEASURE(calcChanOsc,calcChanOsc());
if (mobileUI) { if (mobileUI) {
globalWinFlags=ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoBringToFrontOnFocus; globalWinFlags=ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoBringToFrontOnFocus;
//globalWinFlags=ImGuiWindowFlags_NoTitleBar; //globalWinFlags=ImGuiWindowFlags_NoTitleBar;
// scene handling goes here! // scene handling goes here!
drawMobileControls(); MEASURE(mobileControls,drawMobileControls());
switch (mobScene) { switch (mobScene) {
case GUI_SCENE_ORDERS: case GUI_SCENE_ORDERS:
ordersOpen=true; ordersOpen=true;
curWindow=GUI_WINDOW_ORDERS; curWindow=GUI_WINDOW_ORDERS;
drawOrders(); MEASURE(orders,drawOrders());
break; break;
case GUI_SCENE_INSTRUMENT: case GUI_SCENE_INSTRUMENT:
insEditOpen=true; insEditOpen=true;
curWindow=GUI_WINDOW_INS_EDIT; curWindow=GUI_WINDOW_INS_EDIT;
drawInsEdit(); MEASURE(insEdit,drawInsEdit());
drawPiano(); MEASURE(piano,drawPiano());
break; break;
case GUI_SCENE_WAVETABLE: case GUI_SCENE_WAVETABLE:
waveEditOpen=true; waveEditOpen=true;
curWindow=GUI_WINDOW_WAVE_EDIT; curWindow=GUI_WINDOW_WAVE_EDIT;
drawWaveEdit(); MEASURE(waveEdit,drawWaveEdit());
drawPiano(); MEASURE(piano,drawPiano());
break; break;
case GUI_SCENE_SAMPLE: case GUI_SCENE_SAMPLE:
sampleEditOpen=true; sampleEditOpen=true;
curWindow=GUI_WINDOW_SAMPLE_EDIT; curWindow=GUI_WINDOW_SAMPLE_EDIT;
drawSampleEdit(); MEASURE(sampleEdit,drawSampleEdit());
drawPiano(); MEASURE(piano,drawPiano());
break; break;
case GUI_SCENE_CHANNELS: case GUI_SCENE_CHANNELS:
channelsOpen=true; channelsOpen=true;
curWindow=GUI_WINDOW_CHANNELS; curWindow=GUI_WINDOW_CHANNELS;
drawChannels(); MEASURE(channels,drawChannels());
break; break;
case GUI_SCENE_CHIPS: case GUI_SCENE_CHIPS:
sysManagerOpen=true; sysManagerOpen=true;
curWindow=GUI_WINDOW_SYS_MANAGER; curWindow=GUI_WINDOW_SYS_MANAGER;
drawSysManager(); MEASURE(sysManager,drawSysManager());
break; break;
case GUI_SCENE_MIXER: case GUI_SCENE_MIXER:
mixerOpen=true; mixerOpen=true;
curWindow=GUI_WINDOW_MIXER; curWindow=GUI_WINDOW_MIXER;
drawMixer(); MEASURE(mixer,drawMixer());
break; break;
default: default:
patternOpen=true; patternOpen=true;
curWindow=GUI_WINDOW_PATTERN; curWindow=GUI_WINDOW_PATTERN;
drawPattern(); MEASURE(pattern,drawPattern());
drawPiano(); MEASURE(piano,drawPiano());
drawMobileOrderSel(); MEASURE(mobileOrderSel,drawMobileOrderSel());
globalWinFlags=0; globalWinFlags=0;
drawFindReplace(); MEASURE(findReplace,drawFindReplace());
break; break;
} }
globalWinFlags=0; globalWinFlags=0;
drawSettings(); MEASURE(settings,drawSettings());
drawDebug(); MEASURE(debug,drawDebug());
drawLog(); MEASURE(log,drawLog());
drawCompatFlags(); MEASURE(compatFlags,drawCompatFlags());
drawStats(); MEASURE(stats,drawStats());
} else { } else {
globalWinFlags=0; globalWinFlags=0;
ImGui::DockSpaceOverViewport(NULL,lockLayout?(ImGuiDockNodeFlags_NoWindowMenuButton|ImGuiDockNodeFlags_NoMove|ImGuiDockNodeFlags_NoResize|ImGuiDockNodeFlags_NoCloseButton|ImGuiDockNodeFlags_NoDocking|ImGuiDockNodeFlags_NoDockingSplitMe|ImGuiDockNodeFlags_NoDockingSplitOther):0); ImGui::DockSpaceOverViewport(NULL,lockLayout?(ImGuiDockNodeFlags_NoWindowMenuButton|ImGuiDockNodeFlags_NoMove|ImGuiDockNodeFlags_NoResize|ImGuiDockNodeFlags_NoCloseButton|ImGuiDockNodeFlags_NoDocking|ImGuiDockNodeFlags_NoDockingSplitMe|ImGuiDockNodeFlags_NoDockingSplitOther):0);
drawSubSongs(); MEASURE(subSongs,drawSubSongs());
drawFindReplace(); MEASURE(findReplace,drawFindReplace());
drawSpoiler(); MEASURE(spoiler,drawSpoiler());
drawPattern(); MEASURE(pattern,drawPattern());
drawEditControls(); MEASURE(editControls,drawEditControls());
drawSpeed(); MEASURE(speed,drawSpeed());
if (!basicMode) drawGrooves(); if (!basicMode) {
drawSongInfo(); MEASURE(grooves,drawGrooves());
drawOrders(); }
MEASURE(songInfo,drawSongInfo());
MEASURE(orders,drawOrders());
if (introMonOpen) { if (introMonOpen) {
int totalTicks=e->getTotalTicks(); int totalTicks=e->getTotalTicks();
int totalSeconds=e->getTotalSeconds(); int totalSeconds=e->getTotalSeconds();
@ -4269,36 +4331,38 @@ bool FurnaceGUI::loop() {
if (e->isPlaying()) monitorPos+=ImGui::GetIO().DeltaTime; if (e->isPlaying()) monitorPos+=ImGui::GetIO().DeltaTime;
} }
drawSampleList(); MEASURE(sampleList,drawSampleList());
drawSampleEdit(); MEASURE(sampleEdit,drawSampleEdit());
drawWaveList(); MEASURE(waveList,drawWaveList());
drawWaveEdit(); MEASURE(waveEdit,drawWaveEdit());
drawInsList(); MEASURE(insList,drawInsList());
drawInsEdit(); MEASURE(insEdit,drawInsEdit());
drawMixer(); MEASURE(mixer,drawMixer());
readOsc(); MEASURE(readOsc,readOsc());
drawOsc(); MEASURE(osc,drawOsc());
drawChanOsc(); MEASURE(chanOsc,drawChanOsc());
drawVolMeter(); MEASURE(volMeter,drawVolMeter());
drawSettings(); MEASURE(settings,drawSettings());
drawDebug(); MEASURE(debug,drawDebug());
drawStats(); MEASURE(stats,drawStats());
if (!basicMode) drawCompatFlags();
drawPiano();
drawNotes();
if (!basicMode) { if (!basicMode) {
drawChannels(); MEASURE(compatFlags,drawCompatFlags());
} }
drawPatManager(); MEASURE(piano,drawPiano());
MEASURE(notes,drawNotes());
if (!basicMode) { if (!basicMode) {
drawSysManager(); MEASURE(channels,drawChannels());
} }
drawClock(); MEASURE(patManager,drawPatManager());
drawRegView(); if (!basicMode) {
drawLog(); MEASURE(sysManager,drawSysManager());
drawEffectList(); }
MEASURE(clock,drawClock());
MEASURE(regView,drawRegView());
MEASURE(log,drawLog());
MEASURE(effectList,drawEffectList());
} }
activateTutorial(GUI_TUTORIAL_OVERVIEW); activateTutorial(GUI_TUTORIAL_OVERVIEW);
@ -4960,6 +5024,8 @@ bool FurnaceGUI::loop() {
} }
if (aboutOpen) drawAbout(); if (aboutOpen) drawAbout();
MEASURE_BEGIN(popup);
if (ImGui::BeginPopupModal("Rendering...",NULL,ImGuiWindowFlags_AlwaysAutoResize)) { if (ImGui::BeginPopupModal("Rendering...",NULL,ImGuiWindowFlags_AlwaysAutoResize)) {
ImGui::Text("Please wait..."); ImGui::Text("Please wait...");
if (ImGui::Button("Abort")) { if (ImGui::Button("Abort")) {
@ -5491,12 +5557,16 @@ bool FurnaceGUI::loop() {
ImGui::EndPopup(); ImGui::EndPopup();
} }
MEASURE_END(popup);
if (!tutorial.introPlayed || settings.alwaysPlayIntro!=0) { if (!tutorial.introPlayed || settings.alwaysPlayIntro!=0) {
MEASURE_BEGIN(intro);
initialScreenWipe=0; initialScreenWipe=0;
if (settings.alwaysPlayIntro==1) { if (settings.alwaysPlayIntro==1) {
shortIntro=true; shortIntro=true;
} }
drawIntro(introPos); drawIntro(introPos);
MEASURE_END(intro);
} else { } else {
introPos=12.0; introPos=12.0;
} }
@ -6577,6 +6647,7 @@ FurnaceGUI::FurnaceGUI():
eventTimeBegin(0), eventTimeBegin(0),
eventTimeEnd(0), eventTimeEnd(0),
eventTimeDelta(0), eventTimeDelta(0),
perfMetricsLen(0),
chanToMove(-1), chanToMove(-1),
sysToMove(-1), sysToMove(-1),
sysToDelete(-1), sysToDelete(-1),

View File

@ -1154,6 +1154,17 @@ struct FurnaceGUIImage {
ch(0) {} ch(0) {}
}; };
struct FurnaceGUIPerfMetric {
const char* name;
int elapsed;
FurnaceGUIPerfMetric(const char* n, int t):
name(n),
elapsed(t) {}
FurnaceGUIPerfMetric():
name(NULL),
elapsed(0) {}
};
class FurnaceGUI { class FurnaceGUI {
DivEngine* e; DivEngine* e;
@ -1739,6 +1750,12 @@ class FurnaceGUI {
int renderTimeBegin, renderTimeEnd, renderTimeDelta; int renderTimeBegin, renderTimeEnd, renderTimeDelta;
int eventTimeBegin, eventTimeEnd, eventTimeDelta; int eventTimeBegin, eventTimeEnd, eventTimeDelta;
FurnaceGUIPerfMetric perfMetrics[64];
int perfMetricsLen;
FurnaceGUIPerfMetric perfMetricsLast[64];
int perfMetricsLastLen;
std::map<FurnaceGUIImages,FurnaceGUIImage*> images; std::map<FurnaceGUIImages,FurnaceGUIImage*> images;
int chanToMove, sysToMove, sysToDelete, opToMove; int chanToMove, sysToMove, sysToDelete, opToMove;

View File

@ -1770,6 +1770,21 @@ bool FurnaceGUI::drawSysConf(int chan, DivSystem type, DivConfig& flags, bool mo
} }
break; break;
} }
case DIV_SYSTEM_SEGAPCM:
case DIV_SYSTEM_SEGAPCM_COMPAT: {
bool oldSlides=flags.getBool("oldSlides",false);
if (ImGui::Checkbox("Legacy slides and pitch (compatibility)",&oldSlides)) {
altered=true;
}
if (altered) {
e->lockSave([&]() {
flags.set("oldSlides",oldSlides);
});
}
break;
}
case DIV_SYSTEM_SM8521:/* { case DIV_SYSTEM_SM8521:/* {
bool noAntiClick=flags.getBool("noAntiClick",false); bool noAntiClick=flags.getBool("noAntiClick",false);