From b04e1f2870c9ecc0ec034c773f260e8079c56f18 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Sun, 20 Mar 2022 18:25:48 -0500 Subject: [PATCH] GUI: implement sample draw --- src/engine/playback.cpp | 2 +- src/gui/gui.cpp | 45 +++++++++++++++++++++++++++++++++++++++-- src/gui/gui.h | 1 + src/gui/sampleEdit.cpp | 30 +++++++++++++++++++++++---- 4 files changed, 71 insertions(+), 7 deletions(-) diff --git a/src/engine/playback.cpp b/src/engine/playback.cpp index 16f883e9e..cfa27f5d6 100644 --- a/src/engine/playback.cpp +++ b/src/engine/playback.cpp @@ -1560,7 +1560,7 @@ void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsi return; } - logD("attempts: %d\n",attempts); + //logD("attempts: %d\n",attempts); if (attempts>=100) { logE("hang detected! stopping! at %d seconds %d micro\n",totalSeconds,totalTicks); freelance=false; diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index 57b152ac8..d45f937a1 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -5038,6 +5038,34 @@ void FurnaceGUI::processDrags(int dragX, int dragY) { modified=true; } } + if (sampleDragActive) { + int x=samplePos+(int)(double(dragX-sampleDragStart.x)*sampleZoom); + int x1=samplePos+(int)(double(dragX-sampleDragStart.x+1)*sampleZoom); + if (x<0) x=0; + if (x>=(int)sampleDragLen) x=sampleDragLen-1; + if (x1<0) x1=0; + if (x1>=(int)sampleDragLen) x1=sampleDragLen-1; + double y=0.5-double(dragY-sampleDragStart.y)/sampleDragAreaSize.y; + if (sampleDragMode) { // draw + if (sampleDrag16) { + int val=y*65536; + if (val<-32768) val=-32768; + if (val>32767) val=32767; + for (int i=x; i<=x1; i++) ((short*)sampleDragTarget)[i]=val; + } else { + int val=y*256; + if (val<-128) val=-128; + if (val>127) val=127; + for (int i=x; i<=x1; i++) ((signed char*)sampleDragTarget)[i]=val; + } + updateSampleTex=true; + } else { // select + if (sampleSelStart<0) { + sampleSelStart=x; + } + sampleSelEnd=x; + } + } } #define sysAddOption(x) \ @@ -5287,7 +5315,7 @@ bool FurnaceGUI::loop() { addScroll(1); } } - if (macroDragActive || macroLoopDragActive || waveDragActive) { + if (macroDragActive || macroLoopDragActive || waveDragActive || sampleDragActive) { int distance=fabs(motionXrel); if (distance<1) distance=1; float start=motionX-motionXrel; @@ -5304,7 +5332,7 @@ bool FurnaceGUI::loop() { break; } case SDL_MOUSEBUTTONUP: - if (macroDragActive || macroLoopDragActive || waveDragActive) modified=true; + if (macroDragActive || macroLoopDragActive || waveDragActive || (sampleDragActive && sampleDragMode)) modified=true; macroDragActive=false; macroDragBitMode=false; macroDragInitialValue=false; @@ -5313,6 +5341,19 @@ bool FurnaceGUI::loop() { macroDragLastY=-1; macroLoopDragActive=false; waveDragActive=false; + if (sampleDragActive) { + logD("stopping sample drag\n"); + if (sampleDragMode) { + e->renderSamplesP(); + } else { + if (sampleSelStart>sampleSelEnd) { + sampleSelStart^=sampleSelEnd; + sampleSelEnd^=sampleSelStart; + sampleSelStart^=sampleSelEnd; + } + } + } + sampleDragActive=false; if (selecting) { cursor=selEnd; finishSelection(); diff --git a/src/gui/gui.h b/src/gui/gui.h index 0edbea956..5ffb01814 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -747,6 +747,7 @@ class FurnaceGUI { void* sampleDragTarget; ImVec2 sampleDragStart; ImVec2 sampleDragAreaSize; + unsigned int sampleDragLen; // visualizer float keyHit[DIV_MAX_CHANS]; diff --git a/src/gui/sampleEdit.cpp b/src/gui/sampleEdit.cpp index f63080cf3..f90f3d9c6 100644 --- a/src/gui/sampleEdit.cpp +++ b/src/gui/sampleEdit.cpp @@ -320,7 +320,11 @@ void FurnaceGUI::drawSampleEdit() { if (xCoarse>=sample->samples) break; int y1, y2; int totalAdvance=0; - y1=((unsigned short)sample->data16[xCoarse]^0x8000)*availY/65536; + if (sample->depth==8) { + y1=((unsigned char)sample->data8[xCoarse]^0x80)*availY/256; + } else { + y1=((unsigned short)sample->data16[xCoarse]^0x8000)*availY/65536; + } xFine+=xAdvanceFine; if (xFine>=16777216) { xFine-=16777216; @@ -329,14 +333,22 @@ void FurnaceGUI::drawSampleEdit() { totalAdvance+=xAdvanceCoarse; if (xCoarse>=sample->samples) break; do { - y2=((unsigned short)sample->data16[xCoarse]^0x8000)*availY/65536; + if (sample->depth==8) { + y2=((unsigned char)sample->data8[xCoarse]^0x80)*availY/256; + } else { + y2=((unsigned short)sample->data16[xCoarse]^0x8000)*availY/65536; + } if (y1>y2) { y2^=y1; y1^=y2; y2^=y1; } + if (y1<0) y1=0; + if (y1>=availY) y1=availY-1; + if (y2<0) y2=0; + if (y2>=availY) y2=availY-1; for (int j=y1; j<=y2; j++) { - data[i+availX*j]=lineColor; + data[i+availX*(availY-j-1)]=lineColor; } if (totalAdvance>0) xCoarse++; } while ((totalAdvance--)>0); @@ -348,7 +360,17 @@ void FurnaceGUI::drawSampleEdit() { ImGui::ImageButton(sampleTex,avail,ImVec2(0,0),ImVec2(1,1),0); if (ImGui::IsItemClicked()) { - logD("drawing\n"); + if (sample->samples>0 && (sample->depth==16 || sample->depth==8)) { + sampleDragStart=ImGui::GetItemRectMin(); + sampleDragAreaSize=ImGui::GetItemRectSize(); + sampleDrag16=(sample->depth==16); + sampleDragTarget=(sample->depth==16)?((void*)sample->data16):((void*)sample->data8); + sampleDragLen=sample->samples; + sampleDragActive=true; + sampleSelStart=-1; + sampleSelEnd=-1; + processDrags(ImGui::GetMousePos().x,ImGui::GetMousePos().y); + } } String statusBar=sampleDragMode?"Draw":"Select";