diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index 2c25ab3b40..9cfbc18d92 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -1655,6 +1655,7 @@ void DivEngine::playSub(bool preserveDrift, int goalRow) { ticks=1; tempoAccum=0; totalTicks=0; + totalTicksOff=0; totalSeconds=0; totalTicksR=0; curMidiClock=0; @@ -3726,6 +3727,7 @@ void DivEngine::quitDispatch() { changeOrd=-1; changePos=0; totalTicks=0; + totalTicksOff=0; totalSeconds=0; totalTicksR=0; curMidiClock=0; diff --git a/src/engine/engine.h b/src/engine/engine.h index e6ffecb970..6a8375d84e 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -487,6 +487,7 @@ class DivEngine { double midiTimeDrift; int stepPlay; int changeOrd, changePos, totalSeconds, totalTicks, totalTicksR, curMidiClock, curMidiTime, totalCmds, lastCmds, cmdsPerSecond, globalPitch; + double totalTicksOff; int curMidiTimePiece, curMidiTimeCode; unsigned char extValue, pendingMetroTick; DivGroovePattern speeds; @@ -1451,6 +1452,7 @@ class DivEngine { lastCmds(0), cmdsPerSecond(0), globalPitch(0), + totalTicksOff(0.0), curMidiTimePiece(0), curMidiTimeCode(0), extValue(0), diff --git a/src/engine/playback.cpp b/src/engine/playback.cpp index 0c8f4fdbf4..987b2b7b7c 100644 --- a/src/engine/playback.cpp +++ b/src/engine/playback.cpp @@ -2000,8 +2000,17 @@ bool DivEngine::nextTick(bool noAccum, bool inhibitLowLat) { if (!freelance) { if (stepPlay!=1) { if (!noAccum) { + double dt=divider*tickMult; + if (skipping) { + dt*=(double)virtualTempoN/(double)MAX(1,virtualTempoD); + } totalTicksR++; - totalTicks+=1000000/(divider*tickMult); + totalTicks+=1000000/dt; + totalTicksOff+=fmod(1000000.0,dt); + while (totalTicksOff>=dt) { + totalTicksOff-=dt; + totalTicks++; + } } if (totalTicks>=1000000) { totalTicks-=1000000; diff --git a/src/gui/orders.cpp b/src/gui/orders.cpp index fc7ea16a47..b1a81eaad7 100644 --- a/src/gui/orders.cpp +++ b/src/gui/orders.cpp @@ -87,6 +87,41 @@ void FurnaceGUI::drawMobileOrderSel() { orderScrollLocked=true; orderScrollTolerance=true; } + + // time + if (e->isPlaying() && settings.playbackTime) { + int totalTicks=e->getTotalTicks(); + int totalSeconds=e->getTotalSeconds(); + String info=""; + + if (totalSeconds==0x7fffffff) { + info="∞"; + } else { + if (totalSeconds>=86400) { + int totalDays=totalSeconds/86400; + int totalYears=totalDays/365; + totalDays%=365; + int totalMonths=totalDays/30; + totalDays%=30; + + info+=fmt::sprintf("%dy",totalYears); + info+=fmt::sprintf("%dm",totalMonths); + info+=fmt::sprintf("%dd",totalDays); + } + + if (totalSeconds>=3600) { + info+=fmt::sprintf("%.2d:",(totalSeconds/3600)%24); + } + + info+=fmt::sprintf("%.2d:%.2d.%.2d",(totalSeconds/60)%60,totalSeconds%60,totalTicks/10000); + } + + ImVec2 textSize=ImGui::CalcTextSize(info.c_str()); + + dl->AddRectFilled(ImVec2(11.0f*dpiScale,(size.y*0.5)-(5.0f*dpiScale)),ImVec2((21.0f*dpiScale)+textSize.x,(size.y*0.5)+textSize.y+(5.0f*dpiScale)),ImGui::GetColorU32(ImGuiCol_WindowBg)); + dl->AddRect(ImVec2(11.0f*dpiScale,(size.y*0.5)-(5.0f*dpiScale)),ImVec2((21.0f*dpiScale)+textSize.x,(size.y*0.5)+textSize.y+(5.0f*dpiScale)),ImGui::GetColorU32(ImGuiCol_Border),0,0,dpiScale); + dl->AddText(ImVec2(16.0f*dpiScale,(size.y)*0.5),ImGui::GetColorU32(ImGuiCol_Text),info.c_str()); + } } ImGui::End(); }