mirror of
https://github.com/tildearrow/furnace.git
synced 2024-12-31 20:11:29 +00:00
GUI: prepare for drawing prev/next pat content
This commit is contained in:
parent
b0996371b7
commit
810ee33d11
5 changed files with 117 additions and 8 deletions
|
@ -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) {
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue