GUI: prepare for drawing prev/next pat content
This commit is contained in:
parent
b0996371b7
commit
810ee33d11
|
@ -4851,6 +4851,20 @@ void* DivEngine::getDispatchChanState(int ch) {
|
||||||
return disCont[dispatchOfChan[ch]].dispatch->getChanState(dispatchChanOfChan[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) {
|
void DivEngine::playSub(bool preserveDrift, int goalRow) {
|
||||||
reset();
|
reset();
|
||||||
if (preserveDrift && curOrder==0) return;
|
if (preserveDrift && curOrder==0) return;
|
||||||
|
@ -4900,6 +4914,7 @@ void DivEngine::playSub(bool preserveDrift, int goalRow) {
|
||||||
if (!preserveDrift) {
|
if (!preserveDrift) {
|
||||||
ticks=1;
|
ticks=1;
|
||||||
}
|
}
|
||||||
|
cmdStream.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
int DivEngine::calcBaseFreq(double clock, double divider, int note, bool period) {
|
int DivEngine::calcBaseFreq(double clock, double divider, int note, bool period) {
|
||||||
|
|
|
@ -170,6 +170,7 @@ class DivEngine {
|
||||||
bool exporting;
|
bool exporting;
|
||||||
bool halted;
|
bool halted;
|
||||||
bool forceMono;
|
bool forceMono;
|
||||||
|
bool cmdStreamEnabled;
|
||||||
int ticks, curRow, curOrder, remainingLoops, nextSpeed, divider;
|
int ticks, curRow, curOrder, remainingLoops, nextSpeed, divider;
|
||||||
int cycles, clockDrift, stepPlay;
|
int cycles, clockDrift, stepPlay;
|
||||||
int changeOrd, changePos, totalSeconds, totalTicks, totalTicksR, totalCmds, lastCmds, cmdsPerSecond, globalPitch;
|
int changeOrd, changePos, totalSeconds, totalTicks, totalTicksR, totalCmds, lastCmds, cmdsPerSecond, globalPitch;
|
||||||
|
@ -189,6 +190,7 @@ class DivEngine {
|
||||||
String lastError;
|
String lastError;
|
||||||
String warnings;
|
String warnings;
|
||||||
std::vector<String> audioDevs;
|
std::vector<String> audioDevs;
|
||||||
|
std::vector<DivCommand> cmdStream;
|
||||||
|
|
||||||
struct SamplePreview {
|
struct SamplePreview {
|
||||||
int sample;
|
int sample;
|
||||||
|
@ -519,6 +521,12 @@ class DivEngine {
|
||||||
// get dispatch channel state
|
// get dispatch channel state
|
||||||
void* getDispatchChanState(int chan);
|
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.
|
// set the audio system.
|
||||||
void setAudio(DivAudioEngines which);
|
void setAudio(DivAudioEngines which);
|
||||||
|
|
||||||
|
@ -622,6 +630,7 @@ class DivEngine {
|
||||||
exporting(false),
|
exporting(false),
|
||||||
halted(false),
|
halted(false),
|
||||||
forceMono(false),
|
forceMono(false),
|
||||||
|
cmdStreamEnabled(false),
|
||||||
ticks(0),
|
ticks(0),
|
||||||
curRow(0),
|
curRow(0),
|
||||||
curOrder(0),
|
curOrder(0),
|
||||||
|
|
|
@ -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);
|
printf("%8d | %d: %s(%d, %d)\n",totalTicksR,c.chan,cmdName[c.cmd],c.value,c.value2);
|
||||||
}
|
}
|
||||||
totalCmds++;
|
totalCmds++;
|
||||||
|
if (cmdStreamEnabled && cmdStream.size()<2000) {
|
||||||
|
cmdStream.push_back(c);
|
||||||
|
}
|
||||||
c.chan=dispatchChanOfChan[c.dis];
|
c.chan=dispatchChanOfChan[c.dis];
|
||||||
return disCont[dispatchOfChan[c.dis]].dispatch->dispatch(c);
|
return disCont[dispatchOfChan[c.dis]].dispatch->dispatch(c);
|
||||||
}
|
}
|
||||||
|
|
|
@ -169,7 +169,9 @@ const char* pitchLabel[11]={
|
||||||
|
|
||||||
String getHomeDir();
|
String getHomeDir();
|
||||||
|
|
||||||
ImU32 partTest[256];
|
inline float randRange(float min, float max) {
|
||||||
|
return min+((float)rand()/(float)RAND_MAX)*(max-min);
|
||||||
|
}
|
||||||
|
|
||||||
bool Particle::update() {
|
bool Particle::update() {
|
||||||
pos.x+=speed.x;
|
pos.x+=speed.x;
|
||||||
|
@ -3176,6 +3178,9 @@ void FurnaceGUI::drawPattern() {
|
||||||
}
|
}
|
||||||
if (ImGui::IsItemClicked(ImGuiMouseButton_Right)) {
|
if (ImGui::IsItemClicked(ImGuiMouseButton_Right)) {
|
||||||
fancyPattern=!fancyPattern;
|
fancyPattern=!fancyPattern;
|
||||||
|
e->enableCommandStream(fancyPattern);
|
||||||
|
e->getCommandStream(cmdStream);
|
||||||
|
cmdStream.clear();
|
||||||
}
|
}
|
||||||
for (int i=0; i<chans; i++) {
|
for (int i=0; i<chans; i++) {
|
||||||
if (!e->song.chanShow[i]) continue;
|
if (!e->song.chanShow[i]) continue;
|
||||||
|
@ -3516,8 +3521,45 @@ void FurnaceGUI::drawPattern() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fancyPattern) { // visualizer
|
if (fancyPattern) { // visualizer
|
||||||
|
e->getCommandStream(cmdStream);
|
||||||
ImDrawList* dl=ImGui::GetWindowDrawList();
|
ImDrawList* dl=ImGui::GetWindowDrawList();
|
||||||
ImVec2 off=ImGui::GetWindowPos();
|
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];
|
ImVec2 arrowPoints[7];
|
||||||
for (int i=0; i<chans; i++) {
|
for (int i=0; i<chans; i++) {
|
||||||
DivChannelState* ch=e->getChanState(i);
|
DivChannelState* ch=e->getChanState(i);
|
||||||
|
@ -3528,16 +3570,16 @@ void FurnaceGUI::drawPattern() {
|
||||||
|
|
||||||
if (e->isPlaying()) {
|
if (e->isPlaying()) {
|
||||||
particles.push_back(Particle(
|
particles.push_back(Particle(
|
||||||
partTest,
|
pitchGrad,
|
||||||
(ch->portaNote<=ch->note)?ICON_FA_CHEVRON_DOWN:ICON_FA_CHEVRON_UP,
|
(ch->portaNote<=ch->note)?ICON_FA_CHEVRON_DOWN:ICON_FA_CHEVRON_UP,
|
||||||
off.x+patChanX[i]+fmod(rand(),width),
|
off.x+patChanX[i]+fmod(rand(),width),
|
||||||
off.y+fmod(rand(),MAX(1,ImGui::GetWindowHeight())),
|
off.y+fmod(rand(),MAX(1,ImGui::GetWindowHeight())),
|
||||||
0.0f,
|
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,
|
0.0f,
|
||||||
1.0f,
|
1.0f,
|
||||||
255.0f,
|
255.0f,
|
||||||
18.0f
|
15.0f
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3576,11 +3618,14 @@ void FurnaceGUI::drawPattern() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// particle simulation
|
// particle simulation
|
||||||
|
ImDrawList* fdl=ImGui::GetForegroundDrawList();
|
||||||
for (size_t i=0; i<particles.size(); i++) {
|
for (size_t i=0; i<particles.size(); i++) {
|
||||||
Particle& part=particles[i];
|
Particle& part=particles[i];
|
||||||
if (part.update()) {
|
if (part.update()) {
|
||||||
dl->AddText(
|
fdl->AddText(
|
||||||
part.pos,
|
iconFont,
|
||||||
|
iconFont->FontSize,
|
||||||
|
ImVec2(part.pos.x-iconFont->FontSize*0.5,part.pos.y-iconFont->FontSize*0.5),
|
||||||
part.colors[(int)part.life],
|
part.colors[(int)part.life],
|
||||||
part.type
|
part.type
|
||||||
);
|
);
|
||||||
|
@ -4446,6 +4491,7 @@ void FurnaceGUI::syncSettings() {
|
||||||
settings.restartOnFlagChange=e->getConfInt("restartOnFlagChange",1);
|
settings.restartOnFlagChange=e->getConfInt("restartOnFlagChange",1);
|
||||||
settings.statusDisplay=e->getConfInt("statusDisplay",0);
|
settings.statusDisplay=e->getConfInt("statusDisplay",0);
|
||||||
settings.dpiScale=e->getConfFloat("dpiScale",0.0f);
|
settings.dpiScale=e->getConfFloat("dpiScale",0.0f);
|
||||||
|
settings.viewPrevPattern=e->getConfInt("viewPrevPattern",1);
|
||||||
|
|
||||||
// keybinds
|
// keybinds
|
||||||
LOAD_KEYBIND(GUI_ACTION_OPEN,FURKMOD_CMD|SDLK_o);
|
LOAD_KEYBIND(GUI_ACTION_OPEN,FURKMOD_CMD|SDLK_o);
|
||||||
|
@ -4637,6 +4683,7 @@ void FurnaceGUI::commitSettings() {
|
||||||
e->setConf("restartOnFlagChange",settings.restartOnFlagChange);
|
e->setConf("restartOnFlagChange",settings.restartOnFlagChange);
|
||||||
e->setConf("statusDisplay",settings.statusDisplay);
|
e->setConf("statusDisplay",settings.statusDisplay);
|
||||||
e->setConf("dpiScale",settings.dpiScale);
|
e->setConf("dpiScale",settings.dpiScale);
|
||||||
|
e->setConf("viewPrevPattern",settings.viewPrevPattern);
|
||||||
|
|
||||||
PUT_UI_COLOR(GUI_COLOR_BACKGROUND);
|
PUT_UI_COLOR(GUI_COLOR_BACKGROUND);
|
||||||
PUT_UI_COLOR(GUI_COLOR_FRAME_BACKGROUND);
|
PUT_UI_COLOR(GUI_COLOR_FRAME_BACKGROUND);
|
||||||
|
@ -8468,7 +8515,32 @@ void FurnaceGUI::applyUISettings() {
|
||||||
ImGui::GetStyle()=sty;
|
ImGui::GetStyle()=sty;
|
||||||
|
|
||||||
for (int i=0; i<256; i++) {
|
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
|
// set to 800 for now due to problems with unifont
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
enum FurnaceGUIColors {
|
enum FurnaceGUIColors {
|
||||||
GUI_COLOR_BACKGROUND=0,
|
GUI_COLOR_BACKGROUND=0,
|
||||||
|
@ -411,6 +412,13 @@ class FurnaceGUI {
|
||||||
ImFont* bigFont;
|
ImFont* bigFont;
|
||||||
ImVec4 uiColors[GUI_COLOR_MAX];
|
ImVec4 uiColors[GUI_COLOR_MAX];
|
||||||
ImVec4 volColors[128];
|
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 {
|
struct Settings {
|
||||||
int mainFontSize, patFontSize, iconSize;
|
int mainFontSize, patFontSize, iconSize;
|
||||||
|
@ -444,6 +452,7 @@ class FurnaceGUI {
|
||||||
int restartOnFlagChange;
|
int restartOnFlagChange;
|
||||||
int statusDisplay;
|
int statusDisplay;
|
||||||
float dpiScale;
|
float dpiScale;
|
||||||
|
int viewPrevPattern;
|
||||||
unsigned int maxUndoSteps;
|
unsigned int maxUndoSteps;
|
||||||
String mainFontPath;
|
String mainFontPath;
|
||||||
String patFontPath;
|
String patFontPath;
|
||||||
|
@ -483,6 +492,7 @@ class FurnaceGUI {
|
||||||
restartOnFlagChange(1),
|
restartOnFlagChange(1),
|
||||||
statusDisplay(0),
|
statusDisplay(0),
|
||||||
dpiScale(0.0f),
|
dpiScale(0.0f),
|
||||||
|
viewPrevPattern(1),
|
||||||
maxUndoSteps(100),
|
maxUndoSteps(100),
|
||||||
mainFontPath(""),
|
mainFontPath(""),
|
||||||
patFontPath(""),
|
patFontPath(""),
|
||||||
|
@ -531,7 +541,7 @@ class FurnaceGUI {
|
||||||
note(n) {}
|
note(n) {}
|
||||||
};
|
};
|
||||||
std::vector<ActiveNote> activeNotes;
|
std::vector<ActiveNote> activeNotes;
|
||||||
|
std::vector<DivCommand> cmdStream;
|
||||||
std::vector<Particle> particles;
|
std::vector<Particle> particles;
|
||||||
|
|
||||||
bool wavePreviewOn;
|
bool wavePreviewOn;
|
||||||
|
|
Loading…
Reference in New Issue