GUI: per-chan osc improvements

This commit is contained in:
tildearrow 2023-06-18 04:27:22 -05:00
parent b9414de49d
commit 4776020d05
5 changed files with 265 additions and 132 deletions

View file

@ -74,7 +74,7 @@ void DivPlatformGB::acquire(short** buf, size_t len) {
buf[1][i]=gb->apu_output.final_sample.right;
for (int i=0; i<4; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=(gb->apu_output.current_sample[i].left+gb->apu_output.current_sample[i].right)<<5;
oscBuf[i]->data[oscBuf[i]->needle++]=(gb->apu_output.current_sample[i].left+gb->apu_output.current_sample[i].right)<<6;
}
}
}

View file

@ -58,9 +58,9 @@ void DivPlatformSM8521::acquire(short** buf, size_t len) {
sm8521_sound_tick(&sm8521,8);
buf[0][h]=sm8521.out<<6;
for (int i=0; i<2; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=sm8521.sg[i].base.out<<5;
oscBuf[i]->data[oscBuf[i]->needle++]=sm8521.sg[i].base.out<<7;
}
oscBuf[2]->data[oscBuf[2]->needle++]=sm8521.noise.base.out<<5;
oscBuf[2]->data[oscBuf[2]->needle++]=sm8521.noise.base.out<<7;
}
}

View file

@ -22,6 +22,7 @@
#include "../ta-log.h"
#include "imgui.h"
#include "imgui_internal.h"
#include "misc/cpp/imgui_stdlib.h"
#define FURNACE_FFT_SIZE 4096
#define FURNACE_FFT_RATE 80.0
@ -284,11 +285,37 @@ void FurnaceGUI::drawChanOsc() {
ImGui::ColorPicker4("Color",(float*)&chanOscColor);
}
if (ImGui::Button("OK")) {
chanOscOptions=false;
ImGui::Text("Text format:");
ImGui::SameLine();
ImGui::InputText("##TextFormat",&chanOscTextFormat);
if (ImGui::IsItemHovered()) {
if (ImGui::BeginTooltip()) {
ImGui::TextUnformatted(
"format guide:\n"
"- %c: channel name\n"
"- %C: channel short name\n"
"- %d: channel number (starting from 0)\n"
"- %D: channel number (starting from 1)\n"
"- %i: instrument name\n"
"- %I: instrument number (decimal)\n"
"- %x: instrument number (hex)\n"
"- %s: chip name\n"
"- %S: chip ID\n"
"- %v: volume (decimal)\n"
"- %V: volume (percentage)\n"
"- %b: volume (hex)\n"
"- %%: percent sign"
);
ImGui::EndTooltip();
}
}
ImGui::ColorEdit4("Text color",(float*)&chanOscTextColor);
if (ImGui::Button("OK")) {
chanOscOptions=false;
}
} else {
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding,ImVec2(0.0f,0.0f));
float availY=ImGui::GetContentRegionAvail().y;
if (ImGui::BeginTable("ChanOsc",chanOscCols,ImGuiTableFlags_Borders)) {
@ -411,6 +438,7 @@ void FurnaceGUI::drawChanOsc() {
y-=dcOff;
if (y<-0.5f) y=-0.5f;
if (y>0.5f) y=0.5f;
y*=chanOscAmplify;
waveform[i]=ImLerp(inRect.Min,inRect.Max,ImVec2(x,0.5f-y));
}
}
@ -425,7 +453,86 @@ void FurnaceGUI::drawChanOsc() {
color=chanOscGrad.get(xVal,1.0f-yVal);
}
ImGui::PushClipRect(inRect.Min,inRect.Max,false);
dl->AddPolyline(waveform,precision,color,ImDrawFlags_None,dpiScale);
if (!chanOscTextFormat.empty()) {
String text;
bool inFormat=false;
for (char i: chanOscTextFormat) {
if (inFormat) {
switch (i) {
case 'c':
text+=e->getChannelName(ch);
break;
case 'C':
text+=e->getChannelShortName(ch);
break;
case 'd':
text+=fmt::sprintf("%d",ch);
break;
case 'D':
text+=fmt::sprintf("%d",ch+1);
break;
case 'i': {
DivChannelState* chanState=e->getChanState(ch);
if (chanState==NULL) break;
DivInstrument* ins=e->getIns(chanState->lastIns);
text+=ins->name;
break;
}
case 'I': {
DivChannelState* chanState=e->getChanState(ch);
if (chanState==NULL) break;
text+=fmt::sprintf("%d",chanState->lastIns);
break;
}
case 'x': {
DivChannelState* chanState=e->getChanState(ch);
if (chanState==NULL) break;
if (chanState->lastIns<0) {
text+="??";
} else {
text+=fmt::sprintf("%.2X",chanState->lastIns);
}
break;
}
case 's': {
text+=e->getSystemName(e->sysOfChan[ch]);
break;
}
case 'S': {
text+=fmt::sprintf("%d",e->dispatchOfChan[ch]);
break;
}
case 'v':
break;
case 'V':
break;
case 'b':
break;
case '%':
text+='%';
break;
default:
text+='%';
text+=i;
break;
}
inFormat=false;
} else {
if (i=='%') {
inFormat=true;
} else {
text+=i;
}
}
}
dl->AddText(ImLerp(inRect.Min,inRect.Max,ImVec2(0.0f,0.0f)),ImGui::GetColorU32(chanOscTextColor),text.c_str());
}
ImGui::PopClipRect();
}
}
@ -438,6 +545,7 @@ void FurnaceGUI::drawChanOsc() {
}
ImGui::PopStyleVar();
}
}
if (ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows)) curWindow=GUI_WINDOW_CHAN_OSC;
ImGui::End();
}

View file

@ -5994,13 +5994,22 @@ bool FurnaceGUI::init() {
chanOscCols=e->getConfInt("chanOscCols",3);
chanOscColorX=e->getConfInt("chanOscColorX",GUI_OSCREF_CENTER);
chanOscColorY=e->getConfInt("chanOscColorY",GUI_OSCREF_CENTER);
chanOscTextX=e->getConfFloat("chanOscTextX",0.0f);
chanOscTextY=e->getConfFloat("chanOscTextY",0.0f);
chanOscAmplify=e->getConfFloat("chanOscAmplify",0.95f);
chanOscWindowSize=e->getConfFloat("chanOscWindowSize",20.0f);
chanOscWaveCorr=e->getConfBool("chanOscWaveCorr",true);
chanOscOptions=e->getConfBool("chanOscOptions",false);
chanOscNormalize=e->getConfBool("chanOscNormalize",false);
chanOscTextFormat=e->getConfString("chanOscTextFormat","%c");
chanOscColor.x=e->getConfFloat("chanOscColorR",1.0f);
chanOscColor.y=e->getConfFloat("chanOscColorG",1.0f);
chanOscColor.z=e->getConfFloat("chanOscColorB",1.0f);
chanOscColor.w=e->getConfFloat("chanOscColorA",1.0f);
chanOscTextColor.x=e->getConfFloat("chanOscTextColorR",1.0f);
chanOscTextColor.y=e->getConfFloat("chanOscTextColorG",1.0f);
chanOscTextColor.z=e->getConfFloat("chanOscTextColorB",1.0f);
chanOscTextColor.w=e->getConfFloat("chanOscTextColorA",0.75f);
chanOscUseGrad=e->getConfBool("chanOscUseGrad",false);
chanOscGrad.fromString(e->getConfString("chanOscGrad",""));
chanOscGrad.render();
@ -6487,13 +6496,22 @@ void FurnaceGUI::commitState() {
e->setConf("chanOscCols",chanOscCols);
e->setConf("chanOscColorX",chanOscColorX);
e->setConf("chanOscColorY",chanOscColorY);
e->setConf("chanOscTextX",chanOscTextX);
e->setConf("chanOscTextY",chanOscTextY);
e->setConf("chanOscAmplify",chanOscAmplify);
e->setConf("chanOscWindowSize",chanOscWindowSize);
e->setConf("chanOscWaveCorr",chanOscWaveCorr);
e->setConf("chanOscOptions",chanOscOptions);
e->setConf("chanOscNormalize",chanOscNormalize);
e->setConf("chanOscTextFormat",chanOscTextFormat);
e->setConf("chanOscColorR",chanOscColor.x);
e->setConf("chanOscColorG",chanOscColor.y);
e->setConf("chanOscColorB",chanOscColor.z);
e->setConf("chanOscColorA",chanOscColor.w);
e->setConf("chanOscTextColorR",chanOscTextColor.x);
e->setConf("chanOscTextColorG",chanOscTextColor.y);
e->setConf("chanOscTextColorB",chanOscTextColor.z);
e->setConf("chanOscTextColorA",chanOscTextColor.w);
e->setConf("chanOscUseGrad",chanOscUseGrad);
e->setConf("chanOscGrad",chanOscGrad.toString());
@ -6915,11 +6933,17 @@ FurnaceGUI::FurnaceGUI():
chanOscColorX(GUI_OSCREF_CENTER),
chanOscColorY(GUI_OSCREF_CENTER),
chanOscWindowSize(20.0f),
chanOscTextX(0.0f),
chanOscTextY(0.0f),
chanOscAmplify(0.95f),
chanOscWaveCorr(true),
chanOscOptions(false),
updateChanOscGradTex(true),
chanOscUseGrad(false),
chanOscNormalize(false),
chanOscTextFormat("%c"),
chanOscColor(1.0f,1.0f,1.0f,1.0f),
chanOscTextColor(1.0f,1.0f,1.0f,0.75f),
chanOscGrad(64,64),
chanOscGradTex(NULL),
followLog(true),

View file

@ -1947,9 +1947,10 @@ class FurnaceGUI {
// per-channel oscilloscope
int chanOscCols, chanOscColorX, chanOscColorY;
float chanOscWindowSize;
bool chanOscWaveCorr, chanOscOptions, updateChanOscGradTex, chanOscUseGrad;
ImVec4 chanOscColor;
float chanOscWindowSize, chanOscTextX, chanOscTextY, chanOscAmplify;
bool chanOscWaveCorr, chanOscOptions, updateChanOscGradTex, chanOscUseGrad, chanOscNormalize;
String chanOscTextFormat;
ImVec4 chanOscColor, chanOscTextColor;
Gradient2D chanOscGrad;
void* chanOscGradTex;
float chanOscLP0[DIV_MAX_CHANS];