Merge branch 'tildearrow:master' into master
This commit is contained in:
commit
30a369ccc0
7
TODO.md
7
TODO.md
|
@ -1,12 +1,13 @@
|
||||||
# to-do for 0.6pre1
|
# to-do for 0.6pre1
|
||||||
|
|
||||||
- rewrite the system name detection function anyway
|
|
||||||
- add another FM editor layout
|
|
||||||
- add ability to move selection by dragging
|
- add ability to move selection by dragging
|
||||||
- find and replace
|
|
||||||
- implement Defle slide bug when using E1xy/E2xy and repeating origin note (requires format change)
|
- implement Defle slide bug when using E1xy/E2xy and repeating origin note (requires format change)
|
||||||
|
|
||||||
# to-do for 0.6pre2 (as this requires new data structures)
|
# to-do for 0.6pre2 (as this requires new data structures)
|
||||||
|
|
||||||
|
- rewrite the system name detection function anyway
|
||||||
|
- this involves the addition of a new "system" field in the song (which solves the problem)
|
||||||
|
- songs made in older versions will go through old system name detection for compatibility
|
||||||
- Game Boy envelope macro/sequence
|
- Game Boy envelope macro/sequence
|
||||||
- volume commands should work on Game Boy
|
- volume commands should work on Game Boy
|
||||||
|
- ability to customize `OFF`, `===` and `REL`
|
||||||
|
|
BIN
demos/Funky_Bubbles_OPL3.fur
Normal file
BIN
demos/Funky_Bubbles_OPL3.fur
Normal file
Binary file not shown.
BIN
demos/going_up_a_step_at_time.fur
Normal file
BIN
demos/going_up_a_step_at_time.fur
Normal file
Binary file not shown.
|
@ -21,6 +21,26 @@
|
||||||
#include "../ta-log.h"
|
#include "../ta-log.h"
|
||||||
#include "taAudio.h"
|
#include "taAudio.h"
|
||||||
|
|
||||||
|
String sanitizePortName(const String& name) {
|
||||||
|
#if defined(_WIN32)
|
||||||
|
// remove port number
|
||||||
|
size_t namePos=name.rfind(' ');
|
||||||
|
if (namePos!=String::npos) {
|
||||||
|
return name.substr(0,namePos);
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
#elif defined(__linux__)
|
||||||
|
// remove port location
|
||||||
|
size_t namePos=name.rfind(' ');
|
||||||
|
if (namePos!=String::npos) {
|
||||||
|
return name.substr(0,namePos);
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
#else
|
||||||
|
return name;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
// --- IN ---
|
// --- IN ---
|
||||||
|
|
||||||
bool TAMidiInRtMidi::gather() {
|
bool TAMidiInRtMidi::gather() {
|
||||||
|
@ -56,7 +76,7 @@ std::vector<String> TAMidiInRtMidi::listDevices() {
|
||||||
unsigned int count=port->getPortCount();
|
unsigned int count=port->getPortCount();
|
||||||
logD("got port count.");
|
logD("got port count.");
|
||||||
for (unsigned int i=0; i<count; i++) {
|
for (unsigned int i=0; i<count; i++) {
|
||||||
String name=port->getPortName(i);
|
String name=sanitizePortName(port->getPortName(i));
|
||||||
if (name!="") ret.push_back(name);
|
if (name!="") ret.push_back(name);
|
||||||
}
|
}
|
||||||
} catch (RtMidiError& e) {
|
} catch (RtMidiError& e) {
|
||||||
|
@ -75,8 +95,12 @@ bool TAMidiInRtMidi::openDevice(String name) {
|
||||||
try {
|
try {
|
||||||
bool portOpen=false;
|
bool portOpen=false;
|
||||||
unsigned int count=port->getPortCount();
|
unsigned int count=port->getPortCount();
|
||||||
|
logD("finding port %s...",name);
|
||||||
for (unsigned int i=0; i<count; i++) {
|
for (unsigned int i=0; i<count; i++) {
|
||||||
if (port->getPortName(i)==name) {
|
String portName=sanitizePortName(port->getPortName(i));
|
||||||
|
logV("- %d: %s",i,portName);
|
||||||
|
if (portName==name) {
|
||||||
|
logD("opening port %d...",i);
|
||||||
port->openPort(i);
|
port->openPort(i);
|
||||||
portOpen=true;
|
portOpen=true;
|
||||||
break;
|
break;
|
||||||
|
@ -184,8 +208,12 @@ bool TAMidiOutRtMidi::openDevice(String name) {
|
||||||
try {
|
try {
|
||||||
bool portOpen=false;
|
bool portOpen=false;
|
||||||
unsigned int count=port->getPortCount();
|
unsigned int count=port->getPortCount();
|
||||||
|
logD("finding port %s...",name);
|
||||||
for (unsigned int i=0; i<count; i++) {
|
for (unsigned int i=0; i<count; i++) {
|
||||||
if (port->getPortName(i)==name) {
|
String portName=sanitizePortName(port->getPortName(i));
|
||||||
|
logV("- %d: %s",i,portName);
|
||||||
|
if (portName==name) {
|
||||||
|
logD("opening port %d...",i);
|
||||||
port->openPort(i);
|
port->openPort(i);
|
||||||
portOpen=true;
|
portOpen=true;
|
||||||
break;
|
break;
|
||||||
|
@ -222,7 +250,7 @@ std::vector<String> TAMidiOutRtMidi::listDevices() {
|
||||||
try {
|
try {
|
||||||
unsigned int count=port->getPortCount();
|
unsigned int count=port->getPortCount();
|
||||||
for (unsigned int i=0; i<count; i++) {
|
for (unsigned int i=0; i<count; i++) {
|
||||||
String name=port->getPortName(i);
|
String name=sanitizePortName(port->getPortName(i));
|
||||||
if (name!="") ret.push_back(name);
|
if (name!="") ret.push_back(name);
|
||||||
}
|
}
|
||||||
} catch (RtMidiError& e) {
|
} catch (RtMidiError& e) {
|
||||||
|
|
|
@ -306,7 +306,7 @@ void DivPlatformBubSysWSG::reset() {
|
||||||
for (int i=0; i<2; i++) {
|
for (int i=0; i<2; i++) {
|
||||||
chan[i]=DivPlatformBubSysWSG::Channel();
|
chan[i]=DivPlatformBubSysWSG::Channel();
|
||||||
chan[i].std.setEngine(parent);
|
chan[i].std.setEngine(parent);
|
||||||
chan[i].ws.setEngine(parent);
|
chan[i].ws.setEngine(parent,8);
|
||||||
chan[i].ws.init(NULL,32,15,false);
|
chan[i].ws.init(NULL,32,15,false);
|
||||||
}
|
}
|
||||||
if (dumpWrites) {
|
if (dumpWrites) {
|
||||||
|
|
|
@ -677,6 +677,9 @@ void DivPlatformOPL::muteChannel(int ch, bool mute) {
|
||||||
fm.channel[outChanMap[ch]].muted=mute;
|
fm.channel[outChanMap[ch]].muted=mute;
|
||||||
}
|
}
|
||||||
int ops=(slots[3][ch]!=255 && chan[ch].state.ops==4 && oplType==3)?4:2;
|
int ops=(slots[3][ch]!=255 && chan[ch].state.ops==4 && oplType==3)?4:2;
|
||||||
|
if (ch&1 && ch<12) {
|
||||||
|
if (chan[ch-1].fourOp) return;
|
||||||
|
}
|
||||||
chan[ch].fourOp=(ops==4);
|
chan[ch].fourOp=(ops==4);
|
||||||
update4OpMask=true;
|
update4OpMask=true;
|
||||||
for (int i=0; i<ops; i++) {
|
for (int i=0; i<ops; i++) {
|
||||||
|
|
|
@ -332,7 +332,7 @@ void DivPlatformSCC::reset() {
|
||||||
for (int i=0; i<5; i++) {
|
for (int i=0; i<5; i++) {
|
||||||
chan[i]=DivPlatformSCC::Channel();
|
chan[i]=DivPlatformSCC::Channel();
|
||||||
chan[i].std.setEngine(parent);
|
chan[i].std.setEngine(parent);
|
||||||
chan[i].ws.setEngine(parent);
|
chan[i].ws.setEngine(parent,128);
|
||||||
chan[i].ws.init(NULL,32,255,false);
|
chan[i].ws.init(NULL,32,255,false);
|
||||||
chan[i].vol=15;
|
chan[i].vol=15;
|
||||||
chan[i].outVol=15;
|
chan[i].outVol=15;
|
||||||
|
|
|
@ -243,8 +243,13 @@ void DivWaveSynth::changeWave2(int num) {
|
||||||
first=true;
|
first=true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DivWaveSynth::setEngine(DivEngine* engine) {
|
void DivWaveSynth::setEngine(DivEngine* engine, int waveFloor) {
|
||||||
e=engine;
|
e=engine;
|
||||||
|
memset(wave1,waveFloor,256);
|
||||||
|
memset(wave2,waveFloor,256);
|
||||||
|
for (int i=0; i<256; i++) {
|
||||||
|
output[i]=waveFloor;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DivWaveSynth::init(DivInstrument* which, int w, int h, bool insChanged) {
|
void DivWaveSynth::init(DivInstrument* which, int w, int h, bool insChanged) {
|
||||||
|
|
|
@ -70,7 +70,7 @@ class DivWaveSynth {
|
||||||
* @param insChanged whether the instrument has changed.
|
* @param insChanged whether the instrument has changed.
|
||||||
*/
|
*/
|
||||||
void init(DivInstrument* which, int width, int height, bool insChanged=false);
|
void init(DivInstrument* which, int width, int height, bool insChanged=false);
|
||||||
void setEngine(DivEngine* engine);
|
void setEngine(DivEngine* engine, int waveFloor=0);
|
||||||
DivWaveSynth():
|
DivWaveSynth():
|
||||||
e(NULL),
|
e(NULL),
|
||||||
pos(0),
|
pos(0),
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
#include "IconsFontAwesome4.h"
|
#include "IconsFontAwesome4.h"
|
||||||
#include "misc/cpp/imgui_stdlib.h"
|
#include "misc/cpp/imgui_stdlib.h"
|
||||||
#include "guiConst.h"
|
#include "guiConst.h"
|
||||||
|
#include "intConst.h"
|
||||||
|
#include "../ta-log.h"
|
||||||
|
|
||||||
const char* queryModes[GUI_QUERY_MAX]={
|
const char* queryModes[GUI_QUERY_MAX]={
|
||||||
"ignore",
|
"ignore",
|
||||||
|
@ -17,9 +19,388 @@ const char* queryModes[GUI_QUERY_MAX]={
|
||||||
const char* queryReplaceModes[GUI_QUERY_REPLACE_MAX]={
|
const char* queryReplaceModes[GUI_QUERY_REPLACE_MAX]={
|
||||||
"set",
|
"set",
|
||||||
"add",
|
"add",
|
||||||
|
"add (overflow)",
|
||||||
"clear"
|
"clear"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int queryNote(int note, int octave) {
|
||||||
|
if (note==100) {
|
||||||
|
return 128;
|
||||||
|
} else if (note==101) { // note off and envelope release
|
||||||
|
return 129;
|
||||||
|
} else if (note==102) { // envelope release only
|
||||||
|
return 130;
|
||||||
|
} else if (octave==0 && note==0) {
|
||||||
|
return -61;
|
||||||
|
} else if (note==0 && octave!=0) {
|
||||||
|
return -61; // bug note?
|
||||||
|
}
|
||||||
|
int seek=(note+(signed char)octave*12);
|
||||||
|
if (seek<-60 || seek>=120) {
|
||||||
|
return -61; // out of range note
|
||||||
|
}
|
||||||
|
return seek;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool checkCondition(int mode, int arg, int argMax, int val, bool noteMode=false) {
|
||||||
|
switch (mode) {
|
||||||
|
case GUI_QUERY_IGNORE:
|
||||||
|
return true;
|
||||||
|
break;
|
||||||
|
case GUI_QUERY_MATCH:
|
||||||
|
return (val==arg);
|
||||||
|
break;
|
||||||
|
case GUI_QUERY_MATCH_NOT:
|
||||||
|
return (val!=-1 && val!=arg);
|
||||||
|
break;
|
||||||
|
case GUI_QUERY_RANGE:
|
||||||
|
return (val>=arg && val<=argMax);
|
||||||
|
break;
|
||||||
|
case GUI_QUERY_RANGE_NOT:
|
||||||
|
return (val!=-1 && (val<arg || val>argMax) && (!noteMode || val<120));
|
||||||
|
break;
|
||||||
|
case GUI_QUERY_ANY:
|
||||||
|
return (val!=-1);
|
||||||
|
break;
|
||||||
|
case GUI_QUERY_NONE:
|
||||||
|
return (val==-1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FurnaceGUI::doFind() {
|
||||||
|
int firstOrder=0;
|
||||||
|
int lastOrder=e->curSubSong->ordersLen-1;
|
||||||
|
|
||||||
|
if (curQueryRangeY==1 || curQueryRangeY==2) {
|
||||||
|
firstOrder=curOrder;
|
||||||
|
lastOrder=curOrder;
|
||||||
|
}
|
||||||
|
|
||||||
|
int firstRow=0;
|
||||||
|
int lastRow=e->curSubSong->patLen-1;
|
||||||
|
|
||||||
|
if (curQueryRangeY==1) {
|
||||||
|
firstRow=selStart.y;
|
||||||
|
lastRow=selEnd.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
int firstChan=0;
|
||||||
|
int lastChan=e->getTotalChannelCount()-1;
|
||||||
|
|
||||||
|
if (curQueryRangeX) {
|
||||||
|
firstChan=curQueryRangeXMin;
|
||||||
|
lastChan=curQueryRangeXMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
curQueryResults.clear();
|
||||||
|
|
||||||
|
for (int i=firstOrder; i<=lastOrder; i++) {
|
||||||
|
for (int j=firstRow; j<=lastRow; j++) {
|
||||||
|
for (int k=firstChan; k<=lastChan; k++) {
|
||||||
|
DivPattern* p=e->curPat[k].getPattern(e->curOrders->ord[k][i],false);
|
||||||
|
bool matched=false;
|
||||||
|
for (FurnaceGUIFindQuery& l: curQuery) {
|
||||||
|
if (matched) break;
|
||||||
|
|
||||||
|
if (!checkCondition(l.noteMode,l.note,l.noteMax,queryNote(p->data[j][0],p->data[j][1]),true)) continue;
|
||||||
|
if (!checkCondition(l.insMode,l.ins,l.insMax,p->data[j][2])) continue;
|
||||||
|
if (!checkCondition(l.volMode,l.vol,l.volMax,p->data[j][3])) continue;
|
||||||
|
|
||||||
|
if (l.effectCount>0) {
|
||||||
|
bool notMatched=false;
|
||||||
|
switch (curQueryEffectPos) {
|
||||||
|
case 0: // no
|
||||||
|
for (int m=0; m<l.effectCount; m++) {
|
||||||
|
bool allGood=false;
|
||||||
|
for (int n=0; n<e->curPat[k].effectCols; n++) {
|
||||||
|
if (!checkCondition(l.effectMode[m],l.effect[m],l.effectMax[m],p->data[j][4+n*2])) continue;
|
||||||
|
if (!checkCondition(l.effectValMode[m],l.effectVal[m],l.effectValMax[m],p->data[j][5+n*2])) continue;
|
||||||
|
allGood=true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!allGood) {
|
||||||
|
notMatched=true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 1: { // lax
|
||||||
|
// locate first effect
|
||||||
|
int posOfFirst=-1;
|
||||||
|
for (int m=0; m<e->curPat[k].effectCols; m++) {
|
||||||
|
if (!checkCondition(l.effectMode[0],l.effect[0],l.effectMax[0],p->data[j][4+m*2])) continue;
|
||||||
|
if (!checkCondition(l.effectValMode[0],l.effectVal[0],l.effectValMax[0],p->data[j][5+m*2])) continue;
|
||||||
|
posOfFirst=m;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (posOfFirst<0) {
|
||||||
|
notMatched=true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// make sure we aren't too far to the right
|
||||||
|
if ((posOfFirst+l.effectCount)>e->curPat[k].effectCols) {
|
||||||
|
notMatched=true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// search from first effect location
|
||||||
|
for (int m=0; m<l.effectCount; m++) {
|
||||||
|
if (!checkCondition(l.effectMode[m],l.effect[m],l.effectMax[m],p->data[j][4+(m+posOfFirst)*2])) {
|
||||||
|
notMatched=true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!checkCondition(l.effectValMode[m],l.effectVal[m],l.effectValMax[m],p->data[j][5+(m+posOfFirst)*2])) {
|
||||||
|
notMatched=true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2: // strict
|
||||||
|
int effectMax=l.effectCount;
|
||||||
|
if (effectMax>e->curPat[k].effectCols) {
|
||||||
|
notMatched=true;
|
||||||
|
} else {
|
||||||
|
for (int m=0; m<effectMax; m++) {
|
||||||
|
if (!checkCondition(l.effectMode[m],l.effect[m],l.effectMax[m],p->data[j][4+m*2])) {
|
||||||
|
notMatched=true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!checkCondition(l.effectValMode[m],l.effectVal[m],l.effectValMax[m],p->data[j][5+m*2])) {
|
||||||
|
notMatched=true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (notMatched) continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
matched=true;
|
||||||
|
}
|
||||||
|
if (matched) {
|
||||||
|
curQueryResults.push_back(FurnaceGUIQueryResult(e->getCurrentSubSong(),i,k,j));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
queryViewingResults=true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FurnaceGUI::doReplace() {
|
||||||
|
doFind();
|
||||||
|
queryViewingResults=false;
|
||||||
|
|
||||||
|
bool* touched[DIV_MAX_CHANS];
|
||||||
|
memset(touched,0,DIV_MAX_CHANS*sizeof(bool*));
|
||||||
|
|
||||||
|
for (FurnaceGUIQueryResult& i: curQueryResults) {
|
||||||
|
int patIndex=e->song.subsong[i.subsong]->orders.ord[i.x][i.order];
|
||||||
|
DivPattern* p=e->song.subsong[i.subsong]->pat[i.x].getPattern(patIndex,true);
|
||||||
|
if (touched[i.x]==NULL) {
|
||||||
|
touched[i.x]=new bool[256*256];
|
||||||
|
memset(touched[i.x],0,256*256*sizeof(bool));
|
||||||
|
}
|
||||||
|
if (touched[i.x][(patIndex<<8)|i.y]) continue;
|
||||||
|
touched[i.x][(patIndex<<8)|i.y]=true;
|
||||||
|
if (queryReplaceNoteDo) {
|
||||||
|
switch (queryReplaceNoteMode) {
|
||||||
|
case GUI_QUERY_REPLACE_SET:
|
||||||
|
if (queryReplaceNote==130) { // macro release
|
||||||
|
p->data[i.y][0]=102;
|
||||||
|
p->data[i.y][1]=0;
|
||||||
|
} else if (queryReplaceNote==129) { // note release
|
||||||
|
p->data[i.y][0]=101;
|
||||||
|
p->data[i.y][1]=0;
|
||||||
|
} else if (queryReplaceNote==128) { // note off
|
||||||
|
p->data[i.y][0]=100;
|
||||||
|
p->data[i.y][1]=0;
|
||||||
|
} else if (queryReplaceNote>=-60 && queryReplaceNote<120) { // note
|
||||||
|
p->data[i.y][0]=(queryReplaceNote+60)%12;
|
||||||
|
if (p->data[i.y][0]==0) p->data[i.y][0]=12;
|
||||||
|
p->data[i.y][1]=(unsigned char)((queryReplaceNote-1)/12);
|
||||||
|
} else { // invalid
|
||||||
|
p->data[i.y][0]=0;
|
||||||
|
p->data[i.y][1]=0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GUI_QUERY_REPLACE_ADD:
|
||||||
|
if (p->data[i.y][0]<100) {
|
||||||
|
int note=queryNote(p->data[i.y][0],p->data[i.y][1]);
|
||||||
|
if (note>=-60 && note<120) {
|
||||||
|
note+=queryReplaceNote;
|
||||||
|
if (note<-60) note=-60;
|
||||||
|
if (note>119) note=119;
|
||||||
|
|
||||||
|
p->data[i.y][0]=(note+60)%12;
|
||||||
|
if (p->data[i.y][0]==0) p->data[i.y][0]=12;
|
||||||
|
p->data[i.y][1]=(unsigned char)((note-1)/12);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GUI_QUERY_REPLACE_ADD_OVERFLOW:
|
||||||
|
if (p->data[i.y][0]<100) {
|
||||||
|
int note=queryNote(p->data[i.y][0],p->data[i.y][1]);
|
||||||
|
if (note>=-60 && note<120) {
|
||||||
|
note+=queryReplaceNote;
|
||||||
|
if (note<-60) {
|
||||||
|
while (note<-60) note+=180;
|
||||||
|
} else if (note>119) {
|
||||||
|
while (note>119) note-=180;
|
||||||
|
}
|
||||||
|
|
||||||
|
p->data[i.y][0]=(note+60)%12;
|
||||||
|
if (p->data[i.y][0]==0) p->data[i.y][0]=12;
|
||||||
|
p->data[i.y][1]=(unsigned char)((note-1)/12);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GUI_QUERY_REPLACE_CLEAR:
|
||||||
|
p->data[i.y][0]=0;
|
||||||
|
p->data[i.y][1]=0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (queryReplaceInsDo) {
|
||||||
|
switch (queryReplaceInsMode) {
|
||||||
|
case GUI_QUERY_REPLACE_SET:
|
||||||
|
p->data[i.y][2]=queryReplaceIns;
|
||||||
|
break;
|
||||||
|
case GUI_QUERY_REPLACE_ADD:
|
||||||
|
if (p->data[i.y][2]>=0) {
|
||||||
|
p->data[i.y][2]+=queryReplaceIns;
|
||||||
|
if (p->data[i.y][2]<0) p->data[i.y][2]=0;
|
||||||
|
if (p->data[i.y][2]>255) p->data[i.y][2]=255;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GUI_QUERY_REPLACE_ADD_OVERFLOW:
|
||||||
|
if (p->data[i.y][2]>=0) p->data[i.y][2]=(p->data[i.y][2]+queryReplaceIns)&0xff;
|
||||||
|
break;
|
||||||
|
case GUI_QUERY_REPLACE_CLEAR:
|
||||||
|
p->data[i.y][2]=-1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (queryReplaceVolDo) {
|
||||||
|
switch (queryReplaceVolMode) {
|
||||||
|
case GUI_QUERY_REPLACE_SET:
|
||||||
|
p->data[i.y][3]=queryReplaceVol;
|
||||||
|
break;
|
||||||
|
case GUI_QUERY_REPLACE_ADD:
|
||||||
|
if (p->data[i.y][3]>=0) {
|
||||||
|
p->data[i.y][3]+=queryReplaceVol;
|
||||||
|
if (p->data[i.y][3]<0) p->data[i.y][3]=0;
|
||||||
|
if (p->data[i.y][3]>255) p->data[i.y][3]=255;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GUI_QUERY_REPLACE_ADD_OVERFLOW:
|
||||||
|
if (p->data[i.y][3]>=0) p->data[i.y][3]=(p->data[i.y][3]+queryReplaceVol)&0xff;
|
||||||
|
break;
|
||||||
|
case GUI_QUERY_REPLACE_CLEAR:
|
||||||
|
p->data[i.y][3]=-1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
signed char effectOrder[8];
|
||||||
|
memset(effectOrder,-1,8);
|
||||||
|
|
||||||
|
switch (queryReplaceEffectPos) {
|
||||||
|
case 0: // clear
|
||||||
|
for (int j=0; j<e->song.subsong[i.subsong]->pat[i.x].effectCols; j++) {
|
||||||
|
effectOrder[j]=j;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 1: { // replace matches
|
||||||
|
int placementIndex=0;
|
||||||
|
for (int j=0; j<e->song.subsong[i.subsong]->pat[i.x].effectCols; j++) {
|
||||||
|
if (p->data[i.y][4+j*2]!=-1 || p->data[i.y][5+j*2]!=-1) {
|
||||||
|
effectOrder[placementIndex++]=j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2: { // replace matches then free spaces
|
||||||
|
int placementIndex=0;
|
||||||
|
for (int j=0; j<e->song.subsong[i.subsong]->pat[i.x].effectCols; j++) {
|
||||||
|
if (p->data[i.y][4+j*2]!=-1 || p->data[i.y][5+j*2]!=-1) {
|
||||||
|
effectOrder[placementIndex++]=j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int j=0; j<e->song.subsong[i.subsong]->pat[i.x].effectCols; j++) {
|
||||||
|
if (p->data[i.y][4+j*2]==-1 && p->data[i.y][5+j*2]==-1) {
|
||||||
|
effectOrder[placementIndex++]=j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 3: { // insert in free spaces
|
||||||
|
int placementIndex=0;
|
||||||
|
for (int j=0; j<e->song.subsong[i.subsong]->pat[i.x].effectCols; j++) {
|
||||||
|
if (p->data[i.y][4+j*2]==-1 && p->data[i.y][5+j*2]==-1) {
|
||||||
|
effectOrder[placementIndex++]=j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int j=0; j<queryReplaceEffectCount; j++) {
|
||||||
|
signed char pos=effectOrder[j];
|
||||||
|
if (pos==-1) continue;
|
||||||
|
if (queryReplaceEffectDo[j]) {
|
||||||
|
switch (queryReplaceEffectMode[j]) {
|
||||||
|
case GUI_QUERY_REPLACE_SET:
|
||||||
|
p->data[i.y][4+pos*2]=queryReplaceEffect[j];
|
||||||
|
break;
|
||||||
|
case GUI_QUERY_REPLACE_ADD:
|
||||||
|
if (p->data[i.y][4+pos*2]>=0) {
|
||||||
|
p->data[i.y][4+pos*2]+=queryReplaceEffect[j];
|
||||||
|
if (p->data[i.y][4+pos*2]<0) p->data[i.y][4+pos*2]=0;
|
||||||
|
if (p->data[i.y][4+pos*2]>255) p->data[i.y][4+pos*2]=255;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GUI_QUERY_REPLACE_ADD_OVERFLOW:
|
||||||
|
if (p->data[i.y][4+pos*2]>=0) p->data[i.y][4+pos*2]=(p->data[i.y][4+pos*2]+queryReplaceEffect[j])&0xff;
|
||||||
|
break;
|
||||||
|
case GUI_QUERY_REPLACE_CLEAR:
|
||||||
|
p->data[i.y][4+pos*2]=-1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (queryReplaceEffectValDo[j]) {
|
||||||
|
switch (queryReplaceEffectValMode[j]) {
|
||||||
|
case GUI_QUERY_REPLACE_SET:
|
||||||
|
p->data[i.y][5+pos*2]=queryReplaceEffectVal[j];
|
||||||
|
break;
|
||||||
|
case GUI_QUERY_REPLACE_ADD:
|
||||||
|
if (p->data[i.y][5+pos*2]>=0) {
|
||||||
|
p->data[i.y][5+pos*2]+=queryReplaceEffectVal[j];
|
||||||
|
if (p->data[i.y][5+pos*2]<0) p->data[i.y][5+pos*2]=0;
|
||||||
|
if (p->data[i.y][5+pos*2]>255) p->data[i.y][5+pos*2]=255;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GUI_QUERY_REPLACE_ADD_OVERFLOW:
|
||||||
|
if (p->data[i.y][5+pos*2]>=0) p->data[i.y][5+pos*2]=(p->data[i.y][5+pos*2]+queryReplaceEffectVal[j])&0xff;
|
||||||
|
break;
|
||||||
|
case GUI_QUERY_REPLACE_CLEAR:
|
||||||
|
p->data[i.y][5+pos*2]=-1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i=0; i<DIV_MAX_CHANS; i++) {
|
||||||
|
if (touched[i]!=NULL) delete[] touched[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#define FIRST_VISIBLE(x) (x==GUI_QUERY_MATCH || x==GUI_QUERY_MATCH_NOT || x==GUI_QUERY_RANGE || x==GUI_QUERY_RANGE_NOT)
|
#define FIRST_VISIBLE(x) (x==GUI_QUERY_MATCH || x==GUI_QUERY_MATCH_NOT || x==GUI_QUERY_RANGE || x==GUI_QUERY_RANGE_NOT)
|
||||||
#define SECOND_VISIBLE(x) (x==GUI_QUERY_RANGE || x==GUI_QUERY_RANGE_NOT)
|
#define SECOND_VISIBLE(x) (x==GUI_QUERY_RANGE || x==GUI_QUERY_RANGE_NOT)
|
||||||
|
|
||||||
|
@ -38,13 +419,85 @@ void FurnaceGUI::drawFindReplace() {
|
||||||
int index=0;
|
int index=0;
|
||||||
int eraseIndex=-1;
|
int eraseIndex=-1;
|
||||||
char tempID[1024];
|
char tempID[1024];
|
||||||
|
if (ImGui::BeginTabBar("FindOrReplace")) {
|
||||||
|
if (ImGui::BeginTabItem("Find")) {
|
||||||
|
if (queryViewingResults) {
|
||||||
|
if (!curQueryResults.empty()) {
|
||||||
|
ImVec2 avail=ImGui::GetContentRegionAvail();
|
||||||
|
avail.y-=ImGui::GetFrameHeightWithSpacing();
|
||||||
|
if (ImGui::BeginTable("FindResults",4,ImGuiTableFlags_Borders|ImGuiTableFlags_ScrollY,avail)) {
|
||||||
|
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed,ImGui::CalcTextSize("order").x);
|
||||||
|
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthFixed,ImGui::CalcTextSize("row").x);
|
||||||
|
ImGui::TableSetupColumn("c2",ImGuiTableColumnFlags_WidthStretch);
|
||||||
|
ImGui::TableSetupColumn("c3",ImGuiTableColumnFlags_WidthFixed);
|
||||||
|
|
||||||
|
ImGui::TableSetupScrollFreeze(0,1);
|
||||||
|
|
||||||
|
ImGui::TableNextRow(ImGuiTableRowFlags_Headers);
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Text("order");
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Text("row");
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Text("channel");
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Text("go");
|
||||||
|
|
||||||
|
int index=0;
|
||||||
|
for (FurnaceGUIQueryResult& i: curQueryResults) {
|
||||||
|
ImGui::TableNextRow();
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
if (settings.orderRowsBase==1) {
|
||||||
|
ImGui::Text("%.2X",i.order);
|
||||||
|
} else {
|
||||||
|
ImGui::Text("%d",i.order);
|
||||||
|
}
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
if (settings.patRowsBase==1) {
|
||||||
|
ImGui::Text("%.2X",i.y);
|
||||||
|
} else {
|
||||||
|
ImGui::Text("%d",i.y);
|
||||||
|
}
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Text("%d (%s)",i.x+1,e->getChannelName(i.x));
|
||||||
|
if (ImGui::TableNextColumn()) {
|
||||||
|
snprintf(tempID,1024,ICON_FA_CHEVRON_RIGHT "##_FR%d",index);
|
||||||
|
if (ImGui::Selectable(tempID)) {
|
||||||
|
e->changeSongP(i.subsong);
|
||||||
|
if (e->isPlaying()) {
|
||||||
|
followPattern=false;
|
||||||
|
} else {
|
||||||
|
e->setOrder(i.order);
|
||||||
|
}
|
||||||
|
curOrder=i.order;
|
||||||
|
cursor.xCoarse=i.x;
|
||||||
|
cursor.xFine=0;
|
||||||
|
cursor.y=i.y;
|
||||||
|
selStart=cursor;
|
||||||
|
selEnd=cursor;
|
||||||
|
demandScrollX=true;
|
||||||
|
updateScroll(cursor.y);
|
||||||
|
nextWindow=GUI_WINDOW_PATTERN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
ImGui::EndTable();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ImGui::Text("no matches found!");
|
||||||
|
}
|
||||||
|
if (ImGui::Button("Back")) {
|
||||||
|
queryViewingResults=false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
for (FurnaceGUIFindQuery& i: curQuery) {
|
for (FurnaceGUIFindQuery& i: curQuery) {
|
||||||
|
ImGui::PushID(index+0x100);
|
||||||
if (ImGui::BeginTable("FindRep",4,ImGuiTableFlags_BordersOuter)) {
|
if (ImGui::BeginTable("FindRep",4,ImGuiTableFlags_BordersOuter)) {
|
||||||
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed);
|
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed);
|
||||||
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch,0.5);
|
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch,0.5);
|
||||||
ImGui::TableSetupColumn("c2",ImGuiTableColumnFlags_WidthStretch,0.25);
|
ImGui::TableSetupColumn("c2",ImGuiTableColumnFlags_WidthStretch,0.25);
|
||||||
ImGui::TableSetupColumn("c3",ImGuiTableColumnFlags_WidthStretch,0.25);
|
ImGui::TableSetupColumn("c3",ImGuiTableColumnFlags_WidthStretch,0.25);
|
||||||
ImGui::PushID(index);
|
|
||||||
ImGui::TableNextRow();
|
ImGui::TableNextRow();
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
ImGui::Text("Note");
|
ImGui::Text("Note");
|
||||||
|
@ -273,15 +726,11 @@ void FurnaceGUI::drawFindReplace() {
|
||||||
i.effectCount--;
|
i.effectCount--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ImGui::PopID();
|
|
||||||
ImGui::EndTable();
|
ImGui::EndTable();
|
||||||
}
|
}
|
||||||
|
ImGui::PopID();
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
if (ImGui::Button("Find")) {
|
|
||||||
|
|
||||||
}
|
|
||||||
ImGui::SameLine();
|
|
||||||
if (eraseIndex>=0) {
|
if (eraseIndex>=0) {
|
||||||
curQuery.erase(curQuery.begin()+eraseIndex);
|
curQuery.erase(curQuery.begin()+eraseIndex);
|
||||||
}
|
}
|
||||||
|
@ -289,7 +738,11 @@ void FurnaceGUI::drawFindReplace() {
|
||||||
curQuery.push_back(FurnaceGUIFindQuery());
|
curQuery.push_back(FurnaceGUIFindQuery());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui::BeginTable("QueryLimits",2)) {
|
if (ImGui::BeginTable("QueryLimits",3)) {
|
||||||
|
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed);
|
||||||
|
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch,0.5f);
|
||||||
|
ImGui::TableSetupColumn("c2",ImGuiTableColumnFlags_WidthStretch,0.5f);
|
||||||
|
|
||||||
ImGui::TableNextRow();
|
ImGui::TableNextRow();
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
|
|
||||||
|
@ -332,6 +785,7 @@ void FurnaceGUI::drawFindReplace() {
|
||||||
}
|
}
|
||||||
ImGui::EndDisabled();
|
ImGui::EndDisabled();
|
||||||
|
|
||||||
|
ImGui::TableNextColumn();
|
||||||
ImGui::Text("Match effect position:");
|
ImGui::Text("Match effect position:");
|
||||||
|
|
||||||
if (ImGui::RadioButton("No",curQueryEffectPos==0)) {
|
if (ImGui::RadioButton("No",curQueryEffectPos==0)) {
|
||||||
|
@ -353,43 +807,199 @@ void FurnaceGUI::drawFindReplace() {
|
||||||
ImGui::SetTooltip("match effects only if they appear exactly as specified.");
|
ImGui::SetTooltip("match effects only if they appear exactly as specified.");
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::TableNextRow();
|
|
||||||
ImGui::TableNextColumn();
|
|
||||||
ImGui::Checkbox("From start",&curQueryFromStart);
|
|
||||||
ImGui::TableNextColumn();
|
|
||||||
ImGui::Checkbox("Backwards",&curQueryBackwards);
|
|
||||||
|
|
||||||
ImGui::EndTable();
|
ImGui::EndTable();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui::TreeNode("Replace")) {
|
if (ImGui::Button("Find")) {
|
||||||
if (ImGui::BeginTable("QueryReplace",3)) {
|
doFind();
|
||||||
ImGui::TableNextRow();
|
}
|
||||||
ImGui::TableNextColumn();
|
}
|
||||||
ImGui::Text("Note");
|
ImGui::EndTabItem();
|
||||||
|
}
|
||||||
|
if (ImGui::BeginTabItem("Replace")) {
|
||||||
|
if (ImGui::BeginTable("QueryReplace",3,ImGuiTableFlags_BordersOuter)) {
|
||||||
|
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed);
|
||||||
|
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch,0.5);
|
||||||
|
ImGui::TableSetupColumn("c2",ImGuiTableColumnFlags_WidthStretch,0.5);
|
||||||
|
|
||||||
ImGui::TableNextRow();
|
ImGui::TableNextRow();
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
ImGui::Text("Ins");
|
ImGui::Checkbox("Note",&queryReplaceNoteDo);
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::BeginDisabled(!queryReplaceNoteDo);
|
||||||
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||||
|
ImGui::Combo("##NRMode",&queryReplaceNoteMode,queryReplaceModes,GUI_QUERY_REPLACE_MAX);
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||||
|
if (queryReplaceNoteMode==GUI_QUERY_REPLACE_SET) {
|
||||||
|
if (queryReplaceNote==130) {
|
||||||
|
snprintf(tempID,1024,"REL");
|
||||||
|
} else if (queryReplaceNote==129) {
|
||||||
|
snprintf(tempID,1024,"===");
|
||||||
|
} else if (queryReplaceNote==128) {
|
||||||
|
snprintf(tempID,1024,"OFF");
|
||||||
|
} else if (queryReplaceNote>=-60 && queryReplaceNote<120) {
|
||||||
|
snprintf(tempID,1024,"%s",noteNames[queryReplaceNote+60]);
|
||||||
|
} else {
|
||||||
|
snprintf(tempID,1024,"???");
|
||||||
|
queryReplaceNote=0;
|
||||||
|
}
|
||||||
|
if (ImGui::BeginCombo("##NRValueC",tempID)) {
|
||||||
|
for (int j=0; j<180; j++) {
|
||||||
|
snprintf(tempID,1024,"%s",noteNames[j]);
|
||||||
|
if (ImGui::Selectable(tempID,queryReplaceNote==(j-60))) {
|
||||||
|
queryReplaceNote=j-60;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ImGui::Selectable("OFF",queryReplaceNote==128)) {
|
||||||
|
queryReplaceNote=128;
|
||||||
|
}
|
||||||
|
if (ImGui::Selectable("===",queryReplaceNote==129)) {
|
||||||
|
queryReplaceNote=129;
|
||||||
|
}
|
||||||
|
if (ImGui::Selectable("REL",queryReplaceNote==130)) {
|
||||||
|
queryReplaceNote=130;
|
||||||
|
}
|
||||||
|
ImGui::EndCombo();
|
||||||
|
}
|
||||||
|
} else if (queryReplaceNoteMode==GUI_QUERY_REPLACE_ADD || queryReplaceNoteMode==GUI_QUERY_REPLACE_ADD_OVERFLOW) {
|
||||||
|
if (ImGui::InputInt("##NRValue",&queryReplaceNote,1,12)) {
|
||||||
|
if (queryReplaceNote<-180) queryReplaceNote=-180;
|
||||||
|
if (queryReplaceNote>180) queryReplaceNote=180;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::EndDisabled();
|
||||||
|
|
||||||
ImGui::TableNextRow();
|
ImGui::TableNextRow();
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
ImGui::Text("Volume");
|
ImGui::Checkbox("Ins",&queryReplaceInsDo);
|
||||||
|
|
||||||
/*ImGui::TableNextRow();
|
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
ImGui::Text("Effect");
|
ImGui::BeginDisabled(!queryReplaceInsDo);
|
||||||
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||||
|
ImGui::Combo("##IRMode",&queryReplaceInsMode,queryReplaceModes,GUI_QUERY_REPLACE_MAX);
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||||
|
if (queryReplaceInsMode==GUI_QUERY_REPLACE_SET) {
|
||||||
|
if (ImGui::InputScalar("##IRValueH",ImGuiDataType_S32,&queryReplaceIns,&_ONE,&_SIXTEEN,"%.2X",ImGuiInputTextFlags_CharsHexadecimal)) {
|
||||||
|
if (queryReplaceIns<0) queryReplaceIns=0;
|
||||||
|
if (queryReplaceIns>255) queryReplaceIns=255;
|
||||||
|
}
|
||||||
|
} else if (queryReplaceInsMode==GUI_QUERY_REPLACE_ADD || queryReplaceInsMode==GUI_QUERY_REPLACE_ADD_OVERFLOW) {
|
||||||
|
if (ImGui::InputInt("##IRValue",&queryReplaceIns,1,12)) {
|
||||||
|
if (queryReplaceIns<-255) queryReplaceIns=-255;
|
||||||
|
if (queryReplaceIns>255) queryReplaceIns=255;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::EndDisabled();
|
||||||
|
|
||||||
ImGui::TableNextRow();
|
ImGui::TableNextRow();
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
ImGui::Text("Value");*/
|
ImGui::Checkbox("Volume",&queryReplaceVolDo);
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::BeginDisabled(!queryReplaceVolDo);
|
||||||
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||||
|
ImGui::Combo("##VRMode",&queryReplaceVolMode,queryReplaceModes,GUI_QUERY_REPLACE_MAX);
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||||
|
if (queryReplaceVolMode==GUI_QUERY_REPLACE_SET) {
|
||||||
|
if (ImGui::InputScalar("##VRValueH",ImGuiDataType_S32,&queryReplaceVol,&_ONE,&_SIXTEEN,"%.2X",ImGuiInputTextFlags_CharsHexadecimal)) {
|
||||||
|
if (queryReplaceVol<0) queryReplaceVol=0;
|
||||||
|
if (queryReplaceVol>255) queryReplaceVol=255;
|
||||||
|
}
|
||||||
|
} else if (queryReplaceVolMode==GUI_QUERY_REPLACE_ADD || queryReplaceVolMode==GUI_QUERY_REPLACE_ADD_OVERFLOW) {
|
||||||
|
if (ImGui::InputInt("##VRValue",&queryReplaceVol,1,12)) {
|
||||||
|
if (queryReplaceVol<-255) queryReplaceVol=-255;
|
||||||
|
if (queryReplaceVol>255) queryReplaceVol=255;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::EndDisabled();
|
||||||
|
|
||||||
|
for (int i=0; i<queryReplaceEffectCount; i++) {
|
||||||
|
ImGui::PushID(0x100+i);
|
||||||
|
ImGui::TableNextRow();
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Checkbox("Effect",&queryReplaceEffectDo[i]);
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::BeginDisabled(!queryReplaceEffectDo[i]);
|
||||||
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||||
|
ImGui::Combo("##ERMode",&queryReplaceEffectMode[i],queryReplaceModes,GUI_QUERY_REPLACE_MAX);
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||||
|
if (queryReplaceEffectMode[i]==GUI_QUERY_REPLACE_SET) {
|
||||||
|
if (ImGui::InputScalar("##ERValueH",ImGuiDataType_S32,&queryReplaceEffect[i],&_ONE,&_SIXTEEN,"%.2X",ImGuiInputTextFlags_CharsHexadecimal)) {
|
||||||
|
if (queryReplaceEffect[i]<0) queryReplaceEffect[i]=0;
|
||||||
|
if (queryReplaceEffect[i]>255) queryReplaceEffect[i]=255;
|
||||||
|
}
|
||||||
|
} else if (queryReplaceEffectMode[i]==GUI_QUERY_REPLACE_ADD || queryReplaceEffectMode[i]==GUI_QUERY_REPLACE_ADD_OVERFLOW) {
|
||||||
|
if (ImGui::InputInt("##ERValue",&queryReplaceEffect[i],1,12)) {
|
||||||
|
if (queryReplaceEffect[i]<-255) queryReplaceEffect[i]=-255;
|
||||||
|
if (queryReplaceEffect[i]>255) queryReplaceEffect[i]=255;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::EndDisabled();
|
||||||
|
|
||||||
|
ImGui::TableNextRow();
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Checkbox("Value",&queryReplaceEffectValDo[i]);
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::BeginDisabled(!queryReplaceEffectValDo[i]);
|
||||||
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||||
|
ImGui::Combo("##ERMode",&queryReplaceEffectValMode[i],queryReplaceModes,GUI_QUERY_REPLACE_MAX);
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||||
|
if (queryReplaceEffectValMode[i]==GUI_QUERY_REPLACE_SET) {
|
||||||
|
if (ImGui::InputScalar("##ERValueH",ImGuiDataType_S32,&queryReplaceEffectVal[i],&_ONE,&_SIXTEEN,"%.2X",ImGuiInputTextFlags_CharsHexadecimal)) {
|
||||||
|
if (queryReplaceEffectVal[i]<0) queryReplaceEffectVal[i]=0;
|
||||||
|
if (queryReplaceEffectVal[i]>255) queryReplaceEffectVal[i]=255;
|
||||||
|
}
|
||||||
|
} else if (queryReplaceEffectValMode[i]==GUI_QUERY_REPLACE_ADD || queryReplaceEffectValMode[i]==GUI_QUERY_REPLACE_ADD_OVERFLOW) {
|
||||||
|
if (ImGui::InputInt("##ERValue",&queryReplaceEffectVal[i],1,12)) {
|
||||||
|
if (queryReplaceEffectVal[i]<-255) queryReplaceEffectVal[i]=-255;
|
||||||
|
if (queryReplaceEffectVal[i]>255) queryReplaceEffectVal[i]=255;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::EndDisabled();
|
||||||
|
|
||||||
|
|
||||||
|
ImGui::PopID();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::TableNextRow();
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
if (queryReplaceEffectCount<8) {
|
||||||
|
if (ImGui::Button("Add effect")) {
|
||||||
|
queryReplaceEffectCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
if (queryReplaceEffectCount>0) {
|
||||||
|
if (ImGui::Button("Remove effect")) {
|
||||||
|
queryReplaceEffectCount--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ImGui::EndTable();
|
ImGui::EndTable();
|
||||||
}
|
}
|
||||||
|
ImGui::Text("Effect replace mode:");
|
||||||
|
if (ImGui::RadioButton("Clear effects",queryReplaceEffectPos==0)) {
|
||||||
|
queryReplaceEffectPos=0;
|
||||||
|
}
|
||||||
|
if (ImGui::RadioButton("Replace matches only",queryReplaceEffectPos==1)) {
|
||||||
|
queryReplaceEffectPos=1;
|
||||||
|
}
|
||||||
|
if (ImGui::RadioButton("Replace matches, then free spaces",queryReplaceEffectPos==2)) {
|
||||||
|
queryReplaceEffectPos=2;
|
||||||
|
}
|
||||||
|
if (ImGui::RadioButton("Insert in free spaces",queryReplaceEffectPos==3)) {
|
||||||
|
queryReplaceEffectPos=3;
|
||||||
|
}
|
||||||
if (ImGui::Button("Replace##QueryReplace")) {
|
if (ImGui::Button("Replace##QueryReplace")) {
|
||||||
// TODO
|
doReplace();
|
||||||
}
|
}
|
||||||
ImGui::TreePop();
|
ImGui::EndTabItem();
|
||||||
|
}
|
||||||
|
ImGui::EndTabBar();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows)) curWindow=GUI_WINDOW_FIND;
|
if (ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows)) curWindow=GUI_WINDOW_FIND;
|
||||||
|
|
|
@ -4431,6 +4431,26 @@ FurnaceGUI::FurnaceGUI():
|
||||||
wavePreviewLen(32),
|
wavePreviewLen(32),
|
||||||
wavePreviewHeight(255),
|
wavePreviewHeight(255),
|
||||||
wavePreviewInit(true),
|
wavePreviewInit(true),
|
||||||
|
pgSys(0),
|
||||||
|
pgAddr(0),
|
||||||
|
pgVal(0),
|
||||||
|
curQueryRangeX(false),
|
||||||
|
curQueryBackwards(false),
|
||||||
|
curQueryRangeXMin(0), curQueryRangeXMax(0),
|
||||||
|
curQueryRangeY(0),
|
||||||
|
curQueryEffectPos(0),
|
||||||
|
queryReplaceEffectCount(0),
|
||||||
|
queryReplaceEffectPos(0),
|
||||||
|
queryReplaceNoteMode(0),
|
||||||
|
queryReplaceInsMode(0),
|
||||||
|
queryReplaceVolMode(0),
|
||||||
|
queryReplaceNote(0),
|
||||||
|
queryReplaceIns(0),
|
||||||
|
queryReplaceVol(0),
|
||||||
|
queryReplaceNoteDo(false),
|
||||||
|
queryReplaceInsDo(false),
|
||||||
|
queryReplaceVolDo(false),
|
||||||
|
queryViewingResults(false),
|
||||||
wavePreviewOn(false),
|
wavePreviewOn(false),
|
||||||
wavePreviewKey((SDL_Scancode)0),
|
wavePreviewKey((SDL_Scancode)0),
|
||||||
wavePreviewNote(0),
|
wavePreviewNote(0),
|
||||||
|
@ -4624,4 +4644,11 @@ FurnaceGUI::FurnaceGUI():
|
||||||
|
|
||||||
memset(pianoKeyHit,0,sizeof(float)*180);
|
memset(pianoKeyHit,0,sizeof(float)*180);
|
||||||
memset(pianoKeyPressed,0,sizeof(bool)*180);
|
memset(pianoKeyPressed,0,sizeof(bool)*180);
|
||||||
|
|
||||||
|
memset(queryReplaceEffectMode,0,sizeof(int)*8);
|
||||||
|
memset(queryReplaceEffectValMode,0,sizeof(int)*8);
|
||||||
|
memset(queryReplaceEffect,0,sizeof(int)*8);
|
||||||
|
memset(queryReplaceEffectVal,0,sizeof(int)*8);
|
||||||
|
memset(queryReplaceEffectDo,0,sizeof(bool)*8);
|
||||||
|
memset(queryReplaceEffectValDo,0,sizeof(bool)*8);
|
||||||
}
|
}
|
||||||
|
|
|
@ -818,6 +818,7 @@ enum FurnaceGUIFindQueryModes {
|
||||||
enum FurnaceGUIFindQueryReplaceModes {
|
enum FurnaceGUIFindQueryReplaceModes {
|
||||||
GUI_QUERY_REPLACE_SET=0,
|
GUI_QUERY_REPLACE_SET=0,
|
||||||
GUI_QUERY_REPLACE_ADD,
|
GUI_QUERY_REPLACE_ADD,
|
||||||
|
GUI_QUERY_REPLACE_ADD_OVERFLOW,
|
||||||
GUI_QUERY_REPLACE_CLEAR,
|
GUI_QUERY_REPLACE_CLEAR,
|
||||||
|
|
||||||
GUI_QUERY_REPLACE_MAX
|
GUI_QUERY_REPLACE_MAX
|
||||||
|
@ -855,6 +856,20 @@ struct FurnaceGUIFindQuery {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct FurnaceGUIQueryResult {
|
||||||
|
int subsong, order, x, y;
|
||||||
|
FurnaceGUIQueryResult():
|
||||||
|
subsong(0),
|
||||||
|
order(0),
|
||||||
|
x(0),
|
||||||
|
y(0) {}
|
||||||
|
FurnaceGUIQueryResult(int ss, int o, int xPos, int yPos):
|
||||||
|
subsong(ss),
|
||||||
|
order(o),
|
||||||
|
x(xPos),
|
||||||
|
y(yPos) {}
|
||||||
|
};
|
||||||
|
|
||||||
class FurnaceGUI {
|
class FurnaceGUI {
|
||||||
DivEngine* e;
|
DivEngine* e;
|
||||||
|
|
||||||
|
@ -1170,11 +1185,31 @@ class FurnaceGUI {
|
||||||
int pgSys, pgAddr, pgVal;
|
int pgSys, pgAddr, pgVal;
|
||||||
|
|
||||||
std::vector<FurnaceGUIFindQuery> curQuery;
|
std::vector<FurnaceGUIFindQuery> curQuery;
|
||||||
bool curQueryRangeX, curQueryFromStart, curQueryBackwards;
|
std::vector<FurnaceGUIQueryResult> curQueryResults;
|
||||||
|
bool curQueryRangeX, curQueryBackwards;
|
||||||
int curQueryRangeXMin, curQueryRangeXMax;
|
int curQueryRangeXMin, curQueryRangeXMax;
|
||||||
int curQueryRangeY;
|
int curQueryRangeY;
|
||||||
int curQueryEffectPos;
|
int curQueryEffectPos;
|
||||||
|
|
||||||
|
int queryReplaceEffectCount;
|
||||||
|
int queryReplaceEffectPos;
|
||||||
|
int queryReplaceNoteMode;
|
||||||
|
int queryReplaceInsMode;
|
||||||
|
int queryReplaceVolMode;
|
||||||
|
int queryReplaceEffectMode[8];
|
||||||
|
int queryReplaceEffectValMode[8];
|
||||||
|
int queryReplaceNote;
|
||||||
|
int queryReplaceIns;
|
||||||
|
int queryReplaceVol;
|
||||||
|
int queryReplaceEffect[8];
|
||||||
|
int queryReplaceEffectVal[8];
|
||||||
|
bool queryReplaceNoteDo;
|
||||||
|
bool queryReplaceInsDo;
|
||||||
|
bool queryReplaceVolDo;
|
||||||
|
bool queryReplaceEffectDo[8];
|
||||||
|
bool queryReplaceEffectValDo[8];
|
||||||
|
bool queryViewingResults;
|
||||||
|
|
||||||
struct ActiveNote {
|
struct ActiveNote {
|
||||||
int chan;
|
int chan;
|
||||||
int note;
|
int note;
|
||||||
|
@ -1456,6 +1491,8 @@ class FurnaceGUI {
|
||||||
void doExpand(int multiplier);
|
void doExpand(int multiplier);
|
||||||
void doUndo();
|
void doUndo();
|
||||||
void doRedo();
|
void doRedo();
|
||||||
|
void doFind();
|
||||||
|
void doReplace();
|
||||||
void editOptions(bool topMenu);
|
void editOptions(bool topMenu);
|
||||||
void noteInput(int num, int key, int vol=-1);
|
void noteInput(int num, int key, int vol=-1);
|
||||||
void valueInput(int num, bool direct=false, int target=-1);
|
void valueInput(int num, bool direct=false, int target=-1);
|
||||||
|
|
|
@ -1345,6 +1345,9 @@ void FurnaceGUI::drawMacros(std::vector<FurnaceGUIMacroDesc>& macros) {
|
||||||
#define CENTER_VSLIDER \
|
#define CENTER_VSLIDER \
|
||||||
ImGui::SetCursorPosX(ImGui::GetCursorPosX()+0.5f*ImGui::GetContentRegionAvail().x-10.0f*dpiScale);
|
ImGui::SetCursorPosX(ImGui::GetCursorPosX()+0.5f*ImGui::GetContentRegionAvail().x-10.0f*dpiScale);
|
||||||
|
|
||||||
|
#define CENTER_TEXT_20(text) \
|
||||||
|
ImGui::SetCursorPosX(ImGui::GetCursorPosX()+0.5*(20.0f*dpiScale-ImGui::CalcTextSize(text).x));
|
||||||
|
|
||||||
void FurnaceGUI::drawInsEdit() {
|
void FurnaceGUI::drawInsEdit() {
|
||||||
if (nextWindow==GUI_WINDOW_INS_EDIT) {
|
if (nextWindow==GUI_WINDOW_INS_EDIT) {
|
||||||
insEditOpen=true;
|
insEditOpen=true;
|
||||||
|
@ -2016,7 +2019,452 @@ void FurnaceGUI::drawInsEdit() {
|
||||||
|
|
||||||
ImGui::EndTable();
|
ImGui::EndTable();
|
||||||
}
|
}
|
||||||
|
} else if (settings.fmLayout>=4 && settings.fmLayout<=6) { // alternate
|
||||||
|
int columns=2;
|
||||||
|
switch (settings.fmLayout) {
|
||||||
|
case 4: // 2x2
|
||||||
|
columns=2;
|
||||||
|
break;
|
||||||
|
case 5: // 1x4
|
||||||
|
columns=1;
|
||||||
|
break;
|
||||||
|
case 6: // 4x1
|
||||||
|
columns=opCount;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
char tempID[1024];
|
||||||
|
ImVec2 oldPadding=ImGui::GetStyle().CellPadding;
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding,ImVec2(8.0f*dpiScale,4.0f*dpiScale));
|
||||||
|
if (ImGui::BeginTable("KGE93BSIEO3NOWBDJZBA",columns,ImGuiTableFlags_SizingStretchSame|ImGuiTableFlags_BordersInner)) {
|
||||||
|
for (int i=0; i<opCount; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=ins->fm.op[(opCount==4 && ins->type!=DIV_INS_OPL_DRUMS)?opOrder[i]:i];
|
||||||
|
if ((settings.fmLayout!=6 && ((i+1)&1)) || i==0 || settings.fmLayout==5) ImGui::TableNextRow();
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::PushID(fmt::sprintf("op%d",i).c_str());
|
||||||
|
|
||||||
|
// push colors
|
||||||
|
if (settings.separateFMColors) {
|
||||||
|
bool mod=true;
|
||||||
|
if (ins->type==DIV_INS_OPL_DRUMS) {
|
||||||
|
mod=false;
|
||||||
|
} else if (opCount==4) {
|
||||||
|
if (ins->type==DIV_INS_OPL) {
|
||||||
|
if (opIsOutputOPL[ins->fm.alg&3][i]) mod=false;
|
||||||
} else {
|
} else {
|
||||||
|
if (opIsOutput[ins->fm.alg&7][i]) mod=false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (i==1 || (ins->type==DIV_INS_OPL && (ins->fm.alg&1))) mod=false;
|
||||||
|
}
|
||||||
|
if (mod) {
|
||||||
|
pushAccentColors(
|
||||||
|
uiColors[GUI_COLOR_FM_PRIMARY_MOD],
|
||||||
|
uiColors[GUI_COLOR_FM_SECONDARY_MOD],
|
||||||
|
uiColors[GUI_COLOR_FM_BORDER_MOD],
|
||||||
|
uiColors[GUI_COLOR_FM_BORDER_SHADOW_MOD]
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
pushAccentColors(
|
||||||
|
uiColors[GUI_COLOR_FM_PRIMARY_CAR],
|
||||||
|
uiColors[GUI_COLOR_FM_SECONDARY_CAR],
|
||||||
|
uiColors[GUI_COLOR_FM_BORDER_CAR],
|
||||||
|
uiColors[GUI_COLOR_FM_BORDER_SHADOW_CAR]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::Dummy(ImVec2(dpiScale,dpiScale));
|
||||||
|
if (ins->type==DIV_INS_OPL_DRUMS) {
|
||||||
|
snprintf(tempID,1024,"%s",oplDrumNames[i]);
|
||||||
|
} else if (ins->type==DIV_INS_OPL && ins->fm.opllPreset==16) {
|
||||||
|
if (i==1) {
|
||||||
|
snprintf(tempID,1024,"Envelope 2 (kick only)");
|
||||||
|
} else {
|
||||||
|
snprintf(tempID,1024,"Envelope");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
snprintf(tempID,1024,"Operator %d",i+1);
|
||||||
|
}
|
||||||
|
CENTER_TEXT(tempID);
|
||||||
|
ImGui::TextUnformatted(tempID);
|
||||||
|
|
||||||
|
float sliderHeight=200.0f*dpiScale;
|
||||||
|
float waveWidth=140.0*dpiScale;
|
||||||
|
float waveHeight=sliderHeight-ImGui::GetFrameHeightWithSpacing()*(ins->type==DIV_INS_OPLL?4.5f:5.5f);
|
||||||
|
|
||||||
|
int maxTl=127;
|
||||||
|
if (ins->type==DIV_INS_OPLL) {
|
||||||
|
if (i==1) {
|
||||||
|
maxTl=15;
|
||||||
|
} else {
|
||||||
|
maxTl=63;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS) {
|
||||||
|
maxTl=63;
|
||||||
|
}
|
||||||
|
int maxArDr=(ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ)?31:15;
|
||||||
|
|
||||||
|
bool ssgOn=op.ssgEnv&8;
|
||||||
|
bool ksrOn=op.ksr;
|
||||||
|
bool vibOn=op.vib;
|
||||||
|
bool egtOn=op.egt;
|
||||||
|
bool susOn=op.sus; // yawn
|
||||||
|
unsigned char ssgEnv=op.ssgEnv&7;
|
||||||
|
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding,oldPadding);
|
||||||
|
if (ImGui::BeginTable("opParams",4,ImGuiTableFlags_BordersInnerV)) {
|
||||||
|
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed);
|
||||||
|
ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthFixed,waveWidth);
|
||||||
|
ImGui::TableSetupColumn("c2",ImGuiTableColumnFlags_WidthStretch);
|
||||||
|
ImGui::TableSetupColumn("c3",ImGuiTableColumnFlags_WidthFixed);
|
||||||
|
|
||||||
|
ImGui::TableNextRow();
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
float textY=ImGui::GetCursorPosY();
|
||||||
|
CENTER_TEXT_20(FM_SHORT_NAME(FM_AR));
|
||||||
|
ImGui::TextUnformatted(FM_SHORT_NAME(FM_AR));
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
if (ins->type==DIV_INS_FM) {
|
||||||
|
ImGui::Text("SSG-EG");
|
||||||
|
} else {
|
||||||
|
ImGui::Text("Waveform");
|
||||||
|
}
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Text("Envelope");
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
CENTER_TEXT(FM_SHORT_NAME(FM_TL));
|
||||||
|
ImGui::Text("TL");
|
||||||
|
|
||||||
|
// A/D/S/R
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
|
||||||
|
op.ar&=maxArDr;
|
||||||
|
P(CWVSliderScalar("##AR",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.ar,&maxArDr,&_ZERO));
|
||||||
|
|
||||||
|
ImGui::SameLine();
|
||||||
|
op.dr&=maxArDr;
|
||||||
|
float textX_DR=ImGui::GetCursorPosX();
|
||||||
|
P(CWVSliderScalar("##DR",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.dr,&maxArDr,&_ZERO));
|
||||||
|
|
||||||
|
float textX_SL=0.0f;
|
||||||
|
if (settings.susPosition==0) {
|
||||||
|
ImGui::SameLine();
|
||||||
|
op.sl&=15;
|
||||||
|
textX_SL=ImGui::GetCursorPosX();
|
||||||
|
P(CWVSliderScalar("##SL",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.sl,&_FIFTEEN,&_ZERO));
|
||||||
|
}
|
||||||
|
|
||||||
|
float textX_D2R=0.0f;
|
||||||
|
if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ) {
|
||||||
|
ImGui::SameLine();
|
||||||
|
op.d2r&=31;
|
||||||
|
textX_D2R=ImGui::GetCursorPosX();
|
||||||
|
P(CWVSliderScalar("##D2R",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.d2r,&_THIRTY_ONE,&_ZERO));
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::SameLine();
|
||||||
|
op.rr&=15;
|
||||||
|
float textX_RR=ImGui::GetCursorPosX();
|
||||||
|
P(CWVSliderScalar("##RR",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.rr,&_FIFTEEN,&_ZERO));
|
||||||
|
|
||||||
|
if (settings.susPosition==1) {
|
||||||
|
ImGui::SameLine();
|
||||||
|
op.sl&=15;
|
||||||
|
textX_SL=ImGui::GetCursorPosX();
|
||||||
|
P(CWVSliderScalar("##SL",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.sl,&_FIFTEEN,&_ZERO));
|
||||||
|
}
|
||||||
|
|
||||||
|
ImVec2 prevCurPos=ImGui::GetCursorPos();
|
||||||
|
|
||||||
|
// labels
|
||||||
|
ImGui::SetCursorPos(ImVec2(textX_DR,textY));
|
||||||
|
CENTER_TEXT_20(FM_SHORT_NAME(FM_DR));
|
||||||
|
ImGui::TextUnformatted(FM_SHORT_NAME(FM_DR));
|
||||||
|
|
||||||
|
ImGui::SetCursorPos(ImVec2(textX_SL,textY));
|
||||||
|
CENTER_TEXT_20(FM_SHORT_NAME(FM_SL));
|
||||||
|
ImGui::TextUnformatted(FM_SHORT_NAME(FM_SL));
|
||||||
|
|
||||||
|
ImGui::SetCursorPos(ImVec2(textX_RR,textY));
|
||||||
|
CENTER_TEXT_20(FM_SHORT_NAME(FM_RR));
|
||||||
|
ImGui::TextUnformatted(FM_SHORT_NAME(FM_RR));
|
||||||
|
|
||||||
|
if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ) {
|
||||||
|
ImGui::SetCursorPos(ImVec2(textX_D2R,textY));
|
||||||
|
CENTER_TEXT_20(FM_SHORT_NAME(FM_D2R));
|
||||||
|
ImGui::TextUnformatted(FM_SHORT_NAME(FM_D2R));
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::SetCursorPos(prevCurPos);
|
||||||
|
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
switch (ins->type) {
|
||||||
|
case DIV_INS_FM: {
|
||||||
|
// SSG
|
||||||
|
ImGui::BeginDisabled(!ssgOn);
|
||||||
|
drawSSGEnv(op.ssgEnv&7,ImVec2(waveWidth,waveHeight));
|
||||||
|
ImGui::EndDisabled();
|
||||||
|
if (ImGui::Checkbox("##SSGOn",&ssgOn)) { PARAMETER
|
||||||
|
op.ssgEnv=(op.ssgEnv&7)|(ssgOn<<3);
|
||||||
|
}
|
||||||
|
if (ImGui::IsItemHovered()) {
|
||||||
|
ImGui::SetTooltip("Only for OPN family chips");
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||||
|
if (CWSliderScalar("##SSG",ImGuiDataType_U8,&ssgEnv,&_ZERO,&_SEVEN,ssgEnvTypes[ssgEnv])) { PARAMETER
|
||||||
|
op.ssgEnv=(op.ssgEnv&8)|(ssgEnv&7);
|
||||||
|
}
|
||||||
|
|
||||||
|
// params
|
||||||
|
ImGui::Separator();
|
||||||
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||||
|
snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_MULT));
|
||||||
|
P(CWSliderScalar("##MULT",ImGuiDataType_U8,&op.mult,&_ZERO,&_FIFTEEN,tempID)); rightClickable
|
||||||
|
|
||||||
|
int detune=(op.dt&7)-3;
|
||||||
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||||
|
snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_DT));
|
||||||
|
if (CWSliderInt("##DT",&detune,-3,4,tempID)) { PARAMETER
|
||||||
|
op.dt=detune+3;
|
||||||
|
} rightClickable
|
||||||
|
|
||||||
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||||
|
snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_DT2));
|
||||||
|
P(CWSliderScalar("##DT2",ImGuiDataType_U8,&op.dt2,&_ZERO,&_THREE,tempID)); rightClickable
|
||||||
|
if (ImGui::IsItemHovered()) {
|
||||||
|
ImGui::SetTooltip("Only on YM2151 (OPM)");
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||||
|
snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_RS));
|
||||||
|
P(CWSliderScalar("##RS",ImGuiDataType_U8,&op.rs,&_ZERO,&_THREE,tempID)); rightClickable
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_INS_OPLL:
|
||||||
|
// waveform
|
||||||
|
drawWaveform(i==0?(ins->fm.ams&1):(ins->fm.fms&1),ins->type==DIV_INS_OPZ,ImVec2(waveWidth,waveHeight));
|
||||||
|
|
||||||
|
// params
|
||||||
|
ImGui::Separator();
|
||||||
|
if (ImGui::BeginTable("FMParamsInner",2)) {
|
||||||
|
ImGui::TableNextRow();
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
bool amOn=op.am;
|
||||||
|
if (ImGui::Checkbox(FM_NAME(FM_AM),&amOn)) { PARAMETER
|
||||||
|
op.am=amOn;
|
||||||
|
}
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
if (ImGui::Checkbox(FM_NAME(FM_KSR),&ksrOn)) { PARAMETER
|
||||||
|
op.ksr=ksrOn;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::TableNextRow();
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
if (ImGui::Checkbox(FM_NAME(FM_VIB),&vibOn)) { PARAMETER
|
||||||
|
op.vib=vibOn;
|
||||||
|
}
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
if (ImGui::Checkbox(FM_NAME(FM_EGS),&ssgOn)) { PARAMETER
|
||||||
|
op.ssgEnv=(op.ssgEnv&7)|(ssgOn<<3);
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::EndTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||||
|
snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_MULT));
|
||||||
|
P(CWSliderScalar("##MULT",ImGuiDataType_U8,&op.mult,&_ZERO,&_FIFTEEN,tempID)); rightClickable
|
||||||
|
|
||||||
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||||
|
snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_KSL));
|
||||||
|
P(CWSliderScalar("##KSL",ImGuiDataType_U8,&op.ksl,&_ZERO,&_THREE,tempID)); rightClickable
|
||||||
|
|
||||||
|
break;
|
||||||
|
case DIV_INS_OPL:
|
||||||
|
// waveform
|
||||||
|
drawWaveform(op.ws&7,ins->type==DIV_INS_OPZ,ImVec2(waveWidth,waveHeight));
|
||||||
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||||
|
P(CWSliderScalar("##WS",ImGuiDataType_U8,&op.ws,&_ZERO,&_SEVEN,(ins->type==DIV_INS_OPZ)?opzWaveforms[op.ws&7]:(settings.oplStandardWaveNames?oplWaveformsStandard[op.ws&7]:oplWaveforms[op.ws&7]))); rightClickable
|
||||||
|
if ((ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS) && ImGui::IsItemHovered()) {
|
||||||
|
ImGui::SetTooltip("OPL2/3 only (last 4 waveforms are OPL3 only)");
|
||||||
|
}
|
||||||
|
|
||||||
|
// params
|
||||||
|
ImGui::Separator();
|
||||||
|
if (ImGui::BeginTable("FMParamsInner",2)) {
|
||||||
|
ImGui::TableNextRow();
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
bool amOn=op.am;
|
||||||
|
if (ImGui::Checkbox(FM_NAME(FM_AM),&amOn)) { PARAMETER
|
||||||
|
op.am=amOn;
|
||||||
|
}
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
if (ImGui::Checkbox(FM_NAME(FM_KSR),&ksrOn)) { PARAMETER
|
||||||
|
op.ksr=ksrOn;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::TableNextRow();
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
if (ImGui::Checkbox(FM_NAME(FM_VIB),&vibOn)) { PARAMETER
|
||||||
|
op.vib=vibOn;
|
||||||
|
}
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
if (ImGui::Checkbox(FM_NAME(FM_SUS),&susOn)) { PARAMETER
|
||||||
|
op.sus=susOn;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::EndTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||||
|
snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_MULT));
|
||||||
|
P(CWSliderScalar("##MULT",ImGuiDataType_U8,&op.mult,&_ZERO,&_FIFTEEN,tempID)); rightClickable
|
||||||
|
|
||||||
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||||
|
snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_KSL));
|
||||||
|
P(CWSliderScalar("##KSL",ImGuiDataType_U8,&op.ksl,&_ZERO,&_THREE,tempID)); rightClickable
|
||||||
|
|
||||||
|
break;
|
||||||
|
case DIV_INS_OPZ: {
|
||||||
|
// waveform
|
||||||
|
drawWaveform(op.ws&7,ins->type==DIV_INS_OPZ,ImVec2(waveWidth,waveHeight));
|
||||||
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||||
|
P(CWSliderScalar("##WS",ImGuiDataType_U8,&op.ws,&_ZERO,&_SEVEN,(ins->type==DIV_INS_OPZ)?opzWaveforms[op.ws&7]:(settings.oplStandardWaveNames?oplWaveformsStandard[op.ws&7]:oplWaveforms[op.ws&7]))); rightClickable
|
||||||
|
if ((ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS) && ImGui::IsItemHovered()) {
|
||||||
|
ImGui::SetTooltip("OPL2/3 only (last 4 waveforms are OPL3 only)");
|
||||||
|
}
|
||||||
|
|
||||||
|
// params
|
||||||
|
ImGui::Separator();
|
||||||
|
if (egtOn) {
|
||||||
|
int block=op.dt;
|
||||||
|
int freqNum=(op.mult<<4)|(op.dvb&15);
|
||||||
|
ImGui::Text("Block");
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||||
|
ImVec2 cursorAlign=ImGui::GetCursorPos();
|
||||||
|
if (ImGui::InputInt("##Block",&block,1,1)) {
|
||||||
|
if (block<0) block=0;
|
||||||
|
if (block>7) block=7;
|
||||||
|
op.dt=block;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::Text("Freq");
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::SetCursorPos(ImVec2(cursorAlign.x,ImGui::GetCursorPosY()));
|
||||||
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||||
|
if (ImGui::InputInt("##FreqNum",&freqNum,1,16)) {
|
||||||
|
if (freqNum<0) freqNum=0;
|
||||||
|
if (freqNum>255) freqNum=255;
|
||||||
|
op.mult=freqNum>>4;
|
||||||
|
op.dvb=freqNum&15;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||||
|
snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_MULT));
|
||||||
|
P(CWSliderScalar("##MULT",ImGuiDataType_U8,&op.mult,&_ZERO,&_FIFTEEN,tempID)); rightClickable
|
||||||
|
|
||||||
|
int detune=(op.dt&7)-3;
|
||||||
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||||
|
snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_DT));
|
||||||
|
if (CWSliderInt("##DT",&detune,-3,4,tempID)) { PARAMETER
|
||||||
|
op.dt=detune+3;
|
||||||
|
} rightClickable
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||||
|
snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_DT2));
|
||||||
|
P(CWSliderScalar("##DT2",ImGuiDataType_U8,&op.dt2,&_ZERO,&_THREE,tempID)); rightClickable
|
||||||
|
if (ImGui::IsItemHovered()) {
|
||||||
|
ImGui::SetTooltip("Only on YM2151 (OPM)");
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||||
|
snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_RS));
|
||||||
|
P(CWSliderScalar("##RS",ImGuiDataType_U8,&op.rs,&_ZERO,&_THREE,tempID)); rightClickable
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
float envHeight=sliderHeight;//-ImGui::GetStyle().ItemSpacing.y*2.0f;
|
||||||
|
if (ins->type==DIV_INS_OPZ) {
|
||||||
|
envHeight-=ImGui::GetFrameHeightWithSpacing()*2.0f;
|
||||||
|
}
|
||||||
|
drawFMEnv(op.tl&maxTl,op.ar&maxArDr,op.dr&maxArDr,(ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_OPLL)?((op.rr&15)*2):op.d2r&31,op.rr&15,op.sl&15,op.sus,op.ssgEnv&8,ins->fm.alg,maxTl,maxArDr,ImVec2(ImGui::GetContentRegionAvail().x,envHeight),ins->type);
|
||||||
|
|
||||||
|
if (ins->type==DIV_INS_OPZ) {
|
||||||
|
ImGui::Separator();
|
||||||
|
if (ImGui::BeginTable("FMParamsInnerOPZ",2)) {
|
||||||
|
ImGui::TableNextRow();
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
if (!egtOn) {
|
||||||
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||||
|
snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_FINE));
|
||||||
|
P(CWSliderScalar("##FINE",ImGuiDataType_U8,&op.dvb,&_ZERO,&_FIFTEEN,tempID)); rightClickable
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
bool amOn=op.am;
|
||||||
|
if (ImGui::Checkbox(FM_NAME(FM_AM),&amOn)) { PARAMETER
|
||||||
|
op.am=amOn;
|
||||||
|
}
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::Checkbox("Fixed",&egtOn)) { PARAMETER
|
||||||
|
op.egt=egtOn;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::TableNextRow();
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||||
|
snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_EGSHIFT));
|
||||||
|
P(CWSliderScalar("##EGShift",ImGuiDataType_U8,&op.ksl,&_ZERO,&_THREE,tempID)); rightClickable
|
||||||
|
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||||
|
snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_REV));
|
||||||
|
P(CWSliderScalar("##REV",ImGuiDataType_U8,&op.dam,&_ZERO,&_SEVEN,tempID)); rightClickable
|
||||||
|
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
|
||||||
|
|
||||||
|
ImGui::EndTable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
op.tl&=maxTl;
|
||||||
|
P(CWVSliderScalar("##TL",ImVec2(ImGui::GetFrameHeight(),sliderHeight-(ins->type==DIV_INS_FM?(ImGui::GetFrameHeightWithSpacing()+ImGui::CalcTextSize(FM_SHORT_NAME(FM_AM)).y+ImGui::GetStyle().ItemSpacing.y):0.0f)),ImGuiDataType_U8,&op.tl,&maxTl,&_ZERO));
|
||||||
|
|
||||||
|
if (ins->type==DIV_INS_FM) {
|
||||||
|
CENTER_TEXT(FM_SHORT_NAME(FM_AM));
|
||||||
|
ImGui::TextUnformatted(FM_SHORT_NAME(FM_AM));
|
||||||
|
bool amOn=op.am;
|
||||||
|
if (ImGui::Checkbox("##AM",&amOn)) { PARAMETER
|
||||||
|
op.am=amOn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::EndTable();
|
||||||
|
}
|
||||||
|
ImGui::PopStyleVar();
|
||||||
|
|
||||||
|
if (settings.separateFMColors) {
|
||||||
|
popAccentColors();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::PopID();
|
||||||
|
}
|
||||||
|
ImGui::EndTable();
|
||||||
|
}
|
||||||
|
ImGui::PopStyleVar();
|
||||||
|
} else { // classic
|
||||||
int columns=2;
|
int columns=2;
|
||||||
switch (settings.fmLayout) {
|
switch (settings.fmLayout) {
|
||||||
case 1: // 2x2
|
case 1: // 2x2
|
||||||
|
|
|
@ -25,6 +25,7 @@ const int _THREE=3;
|
||||||
const int _SEVEN=7;
|
const int _SEVEN=7;
|
||||||
const int _TEN=10;
|
const int _TEN=10;
|
||||||
const int _FIFTEEN=15;
|
const int _FIFTEEN=15;
|
||||||
|
const int _SIXTEEN=16;
|
||||||
const int _THIRTY_ONE=31;
|
const int _THIRTY_ONE=31;
|
||||||
const int _SIXTY_FOUR=64;
|
const int _SIXTY_FOUR=64;
|
||||||
const int _ONE_HUNDRED=100;
|
const int _ONE_HUNDRED=100;
|
||||||
|
|
|
@ -27,6 +27,7 @@ extern const int _THREE;
|
||||||
extern const int _SEVEN;
|
extern const int _SEVEN;
|
||||||
extern const int _TEN;
|
extern const int _TEN;
|
||||||
extern const int _FIFTEEN;
|
extern const int _FIFTEEN;
|
||||||
|
extern const int _SIXTEEN;
|
||||||
extern const int _THIRTY_ONE;
|
extern const int _THIRTY_ONE;
|
||||||
extern const int _SIXTY_FOUR;
|
extern const int _SIXTY_FOUR;
|
||||||
extern const int _ONE_HUNDRED;
|
extern const int _ONE_HUNDRED;
|
||||||
|
|
|
@ -1117,6 +1117,15 @@ void FurnaceGUI::drawSettings() {
|
||||||
if (ImGui::RadioButton("Compact (4x1)##fml3",settings.fmLayout==3)) {
|
if (ImGui::RadioButton("Compact (4x1)##fml3",settings.fmLayout==3)) {
|
||||||
settings.fmLayout=3;
|
settings.fmLayout=3;
|
||||||
}
|
}
|
||||||
|
if (ImGui::RadioButton("Alternate (2x2)##fml4",settings.fmLayout==4)) {
|
||||||
|
settings.fmLayout=4;
|
||||||
|
}
|
||||||
|
if (ImGui::RadioButton("Alternate (1x4)##fml5",settings.fmLayout==5)) {
|
||||||
|
settings.fmLayout=5;
|
||||||
|
}
|
||||||
|
if (ImGui::RadioButton("Alternate (4x1)##fml5",settings.fmLayout==6)) {
|
||||||
|
settings.fmLayout=6;
|
||||||
|
}
|
||||||
|
|
||||||
ImGui::Text("Position of Sustain in FM editor:");
|
ImGui::Text("Position of Sustain in FM editor:");
|
||||||
if (ImGui::RadioButton("Between Decay and Sustain Rate##susp0",settings.susPosition==0)) {
|
if (ImGui::RadioButton("Between Decay and Sustain Rate##susp0",settings.susPosition==0)) {
|
||||||
|
@ -2077,7 +2086,7 @@ void FurnaceGUI::syncSettings() {
|
||||||
clampSetting(settings.roundedMenus,0,1);
|
clampSetting(settings.roundedMenus,0,1);
|
||||||
clampSetting(settings.loadJapanese,0,1);
|
clampSetting(settings.loadJapanese,0,1);
|
||||||
clampSetting(settings.loadChinese,0,1);
|
clampSetting(settings.loadChinese,0,1);
|
||||||
clampSetting(settings.fmLayout,0,3);
|
clampSetting(settings.fmLayout,0,6);
|
||||||
clampSetting(settings.susPosition,0,1);
|
clampSetting(settings.susPosition,0,1);
|
||||||
clampSetting(settings.effectCursorDir,0,2);
|
clampSetting(settings.effectCursorDir,0,2);
|
||||||
clampSetting(settings.cursorPastePos,0,1);
|
clampSetting(settings.cursorPastePos,0,1);
|
||||||
|
|
13
src/main.cpp
13
src/main.cpp
|
@ -30,6 +30,7 @@
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#define WIN32_LEAN_AND_MEAN
|
#define WIN32_LEAN_AND_MEAN
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#include <combaseapi.h>
|
||||||
#include <shellapi.h>
|
#include <shellapi.h>
|
||||||
#else
|
#else
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
@ -243,6 +244,12 @@ void initParams() {
|
||||||
// TODO: add crash log
|
// TODO: add crash log
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
initLog();
|
initLog();
|
||||||
|
#ifdef _WIN32
|
||||||
|
HRESULT coResult=CoInitializeEx(NULL,COINIT_MULTITHREADED);
|
||||||
|
if (coResult!=S_OK) {
|
||||||
|
logE("CoInitializeEx failed!");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#if !(defined(__APPLE__) || defined(_WIN32) || defined(ANDROID))
|
#if !(defined(__APPLE__) || defined(_WIN32) || defined(ANDROID))
|
||||||
// workaround for Wayland HiDPI issue
|
// workaround for Wayland HiDPI issue
|
||||||
if (getenv("SDL_VIDEODRIVER")==NULL) {
|
if (getenv("SDL_VIDEODRIVER")==NULL) {
|
||||||
|
@ -446,6 +453,12 @@ int main(int argc, char** argv) {
|
||||||
|
|
||||||
logI("stopping engine.");
|
logI("stopping engine.");
|
||||||
e.quit();
|
e.quit();
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
if (coResult==S_OK || coResult==S_FALSE) {
|
||||||
|
CoUninitialize();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue