GUI: prepare for drawing prev/next pat content

This commit is contained in:
tildearrow 2022-02-16 16:11:15 -05:00
parent b0996371b7
commit 810ee33d11
5 changed files with 117 additions and 8 deletions

View File

@ -4851,6 +4851,20 @@ void* DivEngine::getDispatchChanState(int ch) {
return disCont[dispatchOfChan[ch]].dispatch->getChanState(dispatchChanOfChan[ch]);
}
void DivEngine::enableCommandStream(bool enable) {
cmdStreamEnabled=enable;
}
void DivEngine::getCommandStream(std::vector<DivCommand>& where) {
isBusy.lock();
where.clear();
for (DivCommand& i: cmdStream) {
where.push_back(i);
}
cmdStream.clear();
isBusy.unlock();
}
void DivEngine::playSub(bool preserveDrift, int goalRow) {
reset();
if (preserveDrift && curOrder==0) return;
@ -4900,6 +4914,7 @@ void DivEngine::playSub(bool preserveDrift, int goalRow) {
if (!preserveDrift) {
ticks=1;
}
cmdStream.clear();
}
int DivEngine::calcBaseFreq(double clock, double divider, int note, bool period) {

View File

@ -170,6 +170,7 @@ class DivEngine {
bool exporting;
bool halted;
bool forceMono;
bool cmdStreamEnabled;
int ticks, curRow, curOrder, remainingLoops, nextSpeed, divider;
int cycles, clockDrift, stepPlay;
int changeOrd, changePos, totalSeconds, totalTicks, totalTicksR, totalCmds, lastCmds, cmdsPerSecond, globalPitch;
@ -189,6 +190,7 @@ class DivEngine {
String lastError;
String warnings;
std::vector<String> audioDevs;
std::vector<DivCommand> cmdStream;
struct SamplePreview {
int sample;
@ -519,6 +521,12 @@ class DivEngine {
// get dispatch channel state
void* getDispatchChanState(int chan);
// enable command stream dumping
void enableCommandStream(bool enable);
// get command stream
void getCommandStream(std::vector<DivCommand>& where);
// set the audio system.
void setAudio(DivAudioEngines which);
@ -622,6 +630,7 @@ class DivEngine {
exporting(false),
halted(false),
forceMono(false),
cmdStreamEnabled(false),
ticks(0),
curRow(0),
curOrder(0),

View File

@ -132,6 +132,9 @@ int DivEngine::dispatchCmd(DivCommand c) {
printf("%8d | %d: %s(%d, %d)\n",totalTicksR,c.chan,cmdName[c.cmd],c.value,c.value2);
}
totalCmds++;
if (cmdStreamEnabled && cmdStream.size()<2000) {
cmdStream.push_back(c);
}
c.chan=dispatchChanOfChan[c.dis];
return disCont[dispatchOfChan[c.dis]].dispatch->dispatch(c);
}

View File

@ -169,7 +169,9 @@ const char* pitchLabel[11]={
String getHomeDir();
ImU32 partTest[256];
inline float randRange(float min, float max) {
return min+((float)rand()/(float)RAND_MAX)*(max-min);
}
bool Particle::update() {
pos.x+=speed.x;
@ -3176,6 +3178,9 @@ void FurnaceGUI::drawPattern() {
}
if (ImGui::IsItemClicked(ImGuiMouseButton_Right)) {
fancyPattern=!fancyPattern;
e->enableCommandStream(fancyPattern);
e->getCommandStream(cmdStream);
cmdStream.clear();
}
for (int i=0; i<chans; i++) {
if (!e->song.chanShow[i]) continue;
@ -3516,8 +3521,45 @@ void FurnaceGUI::drawPattern() {
}
if (fancyPattern) { // visualizer
e->getCommandStream(cmdStream);
ImDrawList* dl=ImGui::GetWindowDrawList();
ImVec2 off=ImGui::GetWindowPos();
// commands
for (DivCommand& i: cmdStream) {
if (i.cmd==DIV_CMD_PITCH) continue;
//if (i.cmd==DIV_CMD_NOTE_ON) continue;
if (i.cmd==DIV_CMD_PRE_NOTE) continue;
if (i.cmd==DIV_CMD_INSTRUMENT) continue;
float width=patChanX[i.chan+1]-patChanX[i.chan];
float speedY=-18.0f;
int num=3;
const char* partIcon=ICON_FA_MICROCHIP;
if (i.cmd==DIV_CMD_VOLUME) {
speedY=-18.0f-(10.0f*((float)i.value/(float)e->getMaxVolumeChan(i.chan)));
partIcon=ICON_FA_VOLUME_UP;
num=12.0f*((float)i.value/(float)e->getMaxVolumeChan(i.chan));
}
for (int j=0; j<num; j++) {
particles.push_back(Particle(
noteGrad,
partIcon,
off.x+patChanX[i.chan]+fmod(rand(),width),
off.y+(ImGui::GetWindowHeight()*0.5f)+randRange(0,patFont->FontSize),
randRange(-5,5),
speedY+randRange(-5,5),
0.6f,
1.0f,
255.0f,
8.0f
));
}
}
// note slides
ImVec2 arrowPoints[7];
for (int i=0; i<chans; i++) {
DivChannelState* ch=e->getChanState(i);
@ -3528,16 +3570,16 @@ void FurnaceGUI::drawPattern() {
if (e->isPlaying()) {
particles.push_back(Particle(
partTest,
pitchGrad,
(ch->portaNote<=ch->note)?ICON_FA_CHEVRON_DOWN:ICON_FA_CHEVRON_UP,
off.x+patChanX[i]+fmod(rand(),width),
off.y+fmod(rand(),MAX(1,ImGui::GetWindowHeight())),
0.0f,
(7.0f+(rand()%5)+ch->portaSpeed)*((ch->portaNote<=ch->note)?1:-1),
(7.0f+(rand()%5)+pow(ch->portaSpeed,0.7f))*((ch->portaNote<=ch->note)?1:-1),
0.0f,
1.0f,
255.0f,
18.0f
15.0f
));
}
@ -3576,11 +3618,14 @@ void FurnaceGUI::drawPattern() {
}
// particle simulation
ImDrawList* fdl=ImGui::GetForegroundDrawList();
for (size_t i=0; i<particles.size(); i++) {
Particle& part=particles[i];
if (part.update()) {
dl->AddText(
part.pos,
fdl->AddText(
iconFont,
iconFont->FontSize,
ImVec2(part.pos.x-iconFont->FontSize*0.5,part.pos.y-iconFont->FontSize*0.5),
part.colors[(int)part.life],
part.type
);
@ -4446,6 +4491,7 @@ void FurnaceGUI::syncSettings() {
settings.restartOnFlagChange=e->getConfInt("restartOnFlagChange",1);
settings.statusDisplay=e->getConfInt("statusDisplay",0);
settings.dpiScale=e->getConfFloat("dpiScale",0.0f);
settings.viewPrevPattern=e->getConfInt("viewPrevPattern",1);
// keybinds
LOAD_KEYBIND(GUI_ACTION_OPEN,FURKMOD_CMD|SDLK_o);
@ -4637,6 +4683,7 @@ void FurnaceGUI::commitSettings() {
e->setConf("restartOnFlagChange",settings.restartOnFlagChange);
e->setConf("statusDisplay",settings.statusDisplay);
e->setConf("dpiScale",settings.dpiScale);
e->setConf("viewPrevPattern",settings.viewPrevPattern);
PUT_UI_COLOR(GUI_COLOR_BACKGROUND);
PUT_UI_COLOR(GUI_COLOR_FRAME_BACKGROUND);
@ -8468,7 +8515,32 @@ void FurnaceGUI::applyUISettings() {
ImGui::GetStyle()=sty;
for (int i=0; i<256; i++) {
partTest[i]=ImGui::GetColorU32(ImVec4(1.0f,1.0f,1.0f,(float)i/255.0f));
ImVec4& base=uiColors[GUI_COLOR_PATTERN_EFFECT_PITCH];
pitchGrad[i]=ImGui::GetColorU32(ImVec4(base.x,base.y,base.z,((float)i/255.0f)*base.w));
}
for (int i=0; i<256; i++) {
ImVec4& base=uiColors[GUI_COLOR_PATTERN_ACTIVE];
noteGrad[i]=ImGui::GetColorU32(ImVec4(base.x,base.y,base.z,((float)i/255.0f)*base.w));
}
for (int i=0; i<256; i++) {
ImVec4& base=uiColors[GUI_COLOR_PATTERN_EFFECT_PANNING];
panGrad[i]=ImGui::GetColorU32(ImVec4(base.x,base.y,base.z,((float)i/255.0f)*base.w));
}
for (int i=0; i<256; i++) {
ImVec4& base=uiColors[GUI_COLOR_PATTERN_INS];
insGrad[i]=ImGui::GetColorU32(ImVec4(base.x,base.y,base.z,((float)i/255.0f)*base.w));
}
for (int i=0; i<256; i++) {
ImVec4& base=volColors[i/2];
volGrad[i]=ImGui::GetColorU32(ImVec4(base.x,base.y,base.z,((float)i/255.0f)*base.w));
}
for (int i=0; i<256; i++) {
ImVec4& base=uiColors[GUI_COLOR_PATTERN_EFFECT_SYS_PRIMARY];
sysCmd1Grad[i]=ImGui::GetColorU32(ImVec4(base.x,base.y,base.z,((float)i/255.0f)*base.w));
}
for (int i=0; i<256; i++) {
ImVec4& base=uiColors[GUI_COLOR_PATTERN_EFFECT_SYS_SECONDARY];
sysCmd2Grad[i]=ImGui::GetColorU32(ImVec4(base.x,base.y,base.z,((float)i/255.0f)*base.w));
}
// set to 800 for now due to problems with unifont

View File

@ -24,6 +24,7 @@
#include <SDL.h>
#include <deque>
#include <map>
#include <vector>
enum FurnaceGUIColors {
GUI_COLOR_BACKGROUND=0,
@ -411,6 +412,13 @@ class FurnaceGUI {
ImFont* bigFont;
ImVec4 uiColors[GUI_COLOR_MAX];
ImVec4 volColors[128];
ImU32 pitchGrad[256];
ImU32 volGrad[256];
ImU32 noteGrad[256];
ImU32 panGrad[256];
ImU32 insGrad[256];
ImU32 sysCmd1Grad[256];
ImU32 sysCmd2Grad[256];
struct Settings {
int mainFontSize, patFontSize, iconSize;
@ -444,6 +452,7 @@ class FurnaceGUI {
int restartOnFlagChange;
int statusDisplay;
float dpiScale;
int viewPrevPattern;
unsigned int maxUndoSteps;
String mainFontPath;
String patFontPath;
@ -483,6 +492,7 @@ class FurnaceGUI {
restartOnFlagChange(1),
statusDisplay(0),
dpiScale(0.0f),
viewPrevPattern(1),
maxUndoSteps(100),
mainFontPath(""),
patFontPath(""),
@ -531,7 +541,7 @@ class FurnaceGUI {
note(n) {}
};
std::vector<ActiveNote> activeNotes;
std::vector<DivCommand> cmdStream;
std::vector<Particle> particles;
bool wavePreviewOn;