From f80a2b886412b3cbf3dbbc87ba06abccc7571fd1 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Sun, 19 Mar 2023 03:12:08 -0500 Subject: [PATCH] GUI: make playing needles in sample editor work currently only for YM2612 but I will implement more soon --- src/engine/dispatch.h | 25 +++++++++++++++++++- src/engine/engine.cpp | 5 ++++ src/engine/engine.h | 3 +++ src/engine/platform/abstract.cpp | 4 ++++ src/engine/platform/genesis.cpp | 10 ++++++++ src/engine/platform/genesis.h | 1 + src/gui/sampleEdit.cpp | 40 ++++++++++++++++++++++++++++++++ 7 files changed, 87 insertions(+), 1 deletion(-) diff --git a/src/engine/dispatch.h b/src/engine/dispatch.h index 9a87cc874..1d5932b69 100644 --- a/src/engine/dispatch.h +++ b/src/engine/dispatch.h @@ -293,6 +293,18 @@ struct DivDelayedWrite { write(a,v) {} }; +struct DivSamplePos { + int sample, pos, freq; + DivSamplePos(int s, int p, int f): + sample(s), + pos(p), + freq(f) {} + DivSamplePos(): + sample(-1), + pos(0), + freq(0) {} +}; + struct DivDispatchOscBuffer { bool follow; unsigned int rate; @@ -371,18 +383,29 @@ class DivDispatch { /** * get the state of a channel. + * @param chan the channel. * @return a pointer, or NULL. */ virtual void* getChanState(int chan); /** - * get the DivMacroInt of a chanmel. + * get the DivMacroInt of a channel. + * @param chan the channel. * @return a pointer, or NULL. */ virtual DivMacroInt* getChanMacroInt(int chan); + /** + * get currently playing sample (and its position). + * @param chan the channel. + * @return a DivSamplePos. if sample is -1 then nothing is playing or the + * channel doesn't play samples. + */ + virtual DivSamplePos getSamplePos(int chan); + /** * get an oscilloscope buffer for a channel. + * @param chan the channel. * @return a pointer to a DivDispatchOscBuffer, or NULL if not supported. */ virtual DivDispatchOscBuffer* getOscBuffer(int chan); diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index d03b83b57..a45a19cba 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -2119,6 +2119,11 @@ DivMacroInt* DivEngine::getMacroInt(int chan) { return disCont[dispatchOfChan[chan]].dispatch->getChanMacroInt(dispatchChanOfChan[chan]); } +DivSamplePos DivEngine::getSamplePos(int chan) { + if (chan<0 || chan>=chans) return DivSamplePos(); + return disCont[dispatchOfChan[chan]].dispatch->getSamplePos(dispatchChanOfChan[chan]); +} + DivDispatchOscBuffer* DivEngine::getOscBuffer(int chan) { if (chan<0 || chan>=chans) return NULL; return disCont[dispatchOfChan[chan]].dispatch->getOscBuffer(dispatchChanOfChan[chan]); diff --git a/src/engine/engine.h b/src/engine/engine.h index 7b84f5da2..c15302ba9 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -914,6 +914,9 @@ class DivEngine { // get macro interpreter DivMacroInt* getMacroInt(int chan); + // get sample position + DivSamplePos getSamplePos(int chan); + // get osc buffer DivDispatchOscBuffer* getOscBuffer(int chan); diff --git a/src/engine/platform/abstract.cpp b/src/engine/platform/abstract.cpp index 74ec8cddf..82694e003 100644 --- a/src/engine/platform/abstract.cpp +++ b/src/engine/platform/abstract.cpp @@ -37,6 +37,10 @@ DivMacroInt* DivDispatch::getChanMacroInt(int chan) { return NULL; } +DivSamplePos DivDispatch::getSamplePos(int chan) { + return DivSamplePos(); +} + DivDispatchOscBuffer* DivDispatch::getOscBuffer(int chan) { return NULL; } diff --git a/src/engine/platform/genesis.cpp b/src/engine/platform/genesis.cpp index 6cf1837dd..9491b07bf 100644 --- a/src/engine/platform/genesis.cpp +++ b/src/engine/platform/genesis.cpp @@ -1209,6 +1209,16 @@ DivMacroInt* DivPlatformGenesis::getChanMacroInt(int ch) { return &chan[ch].std; } +DivSamplePos DivPlatformGenesis::getSamplePos(int ch) { + if (ch<5) return DivSamplePos(); + if (ch>5 && !softPCM) return DivSamplePos(); + return DivSamplePos( + chan[ch].dacSample, + chan[ch].dacPos, + chan[ch].dacRate + ); +} + DivDispatchOscBuffer* DivPlatformGenesis::getOscBuffer(int ch) { return oscBuf[ch]; } diff --git a/src/engine/platform/genesis.h b/src/engine/platform/genesis.h index 4c3d57137..210fca9d0 100644 --- a/src/engine/platform/genesis.h +++ b/src/engine/platform/genesis.h @@ -105,6 +105,7 @@ class DivPlatformGenesis: public DivPlatformOPN { int dispatch(DivCommand c); void* getChanState(int chan); DivMacroInt* getChanMacroInt(int ch); + DivSamplePos getSamplePos(int ch); DivDispatchOscBuffer* getOscBuffer(int chan); unsigned char* getRegisterPool(); int getRegisterPoolSize(); diff --git a/src/gui/sampleEdit.cpp b/src/gui/sampleEdit.cpp index 115223cc8..9200b6829 100644 --- a/src/gui/sampleEdit.cpp +++ b/src/gui/sampleEdit.cpp @@ -1407,6 +1407,46 @@ void FurnaceGUI::drawSampleEdit() { dl->AddLine(p1,p2,ImGui::GetColorU32(posColor)); } + if (e->isRunning()) { + for (int i=0; igetTotalChannelCount(); i++) { + DivSamplePos chanPos=e->getSamplePos(i); + if (chanPos.sample!=curSample) continue; + + int start=sampleSelStart; + int end=sampleSelEnd; + if (start>end) { + start^=end; + end^=start; + start^=end; + } + ImDrawList* dl=ImGui::GetWindowDrawList(); + ImVec2 p1=rectMin; + p1.x+=(chanPos.pos-samplePos)/sampleZoom; + ImVec4 posColor=uiColors[GUI_COLOR_SAMPLE_NEEDLE_PLAYING]; + ImVec4 posTrail1=posColor; + ImVec4 posTrail2=posColor; + posTrail1.w*=0.5f; + posTrail2.w=0.0f; + float trailDistance=((float)chanPos.freq/100.0f)/sampleZoom; + + if (p1.xrectMax.x) p1.x=rectMax.x; + + ImVec2 p2=p1; + p2.y=rectMax.y; + + dl->AddRectFilledMultiColor( + ImVec2(p1.x-trailDistance,p1.y), + p2, + ImGui::GetColorU32(posTrail2), + ImGui::GetColorU32(posTrail1), + ImGui::GetColorU32(posTrail1), + ImGui::GetColorU32(posTrail2) + ); + dl->AddLine(p1,p2,ImGui::GetColorU32(posColor)); + } + } + if (drawSelection) { int start=sampleSelStart; int end=sampleSelEnd;