Merge branch 'master' into SID3
This commit is contained in:
commit
47f36f99d9
188 changed files with 5790 additions and 546 deletions
|
|
@ -300,6 +300,7 @@ const char* aboutLine[]={
|
|||
_N("PowerNoise emulator by scratchminer"),
|
||||
_N("ep128emu by Istvan Varga"),
|
||||
_N("NDS sound emulator by cam900"),
|
||||
_N("openMSX YMF278 emulator (modified version) by the openMSX developers"),
|
||||
_N("SID2 emulator by LTVA (modification of reSID emulator)"),
|
||||
_N("SID3 emulator by LTVA"),
|
||||
"",
|
||||
|
|
|
|||
|
|
@ -69,6 +69,9 @@ void FurnaceGUI::startSelection(int xCoarse, int xFine, int y, bool fullRow) {
|
|||
selStart.y=y;
|
||||
selEnd.y=y;
|
||||
} else {
|
||||
if (xCoarse!=cursor.xCoarse || y!=cursor.y) {
|
||||
makeCursorUndo();
|
||||
}
|
||||
cursor.xCoarse=xCoarse;
|
||||
cursor.xFine=xFine;
|
||||
cursor.y=y;
|
||||
|
|
@ -208,6 +211,9 @@ void FurnaceGUI::finishSelection() {
|
|||
}
|
||||
|
||||
void FurnaceGUI::moveCursor(int x, int y, bool select) {
|
||||
if (y>=editStepCoarse || y<=-editStepCoarse || x<=-5 || x>=5 ) {
|
||||
makeCursorUndo();
|
||||
}
|
||||
if (!select) {
|
||||
finishSelection();
|
||||
}
|
||||
|
|
@ -326,6 +332,7 @@ void FurnaceGUI::moveCursor(int x, int y, bool select) {
|
|||
}
|
||||
|
||||
void FurnaceGUI::moveCursorPrevChannel(bool overflow) {
|
||||
makeCursorUndo();
|
||||
finishSelection();
|
||||
curNibble=false;
|
||||
|
||||
|
|
@ -354,6 +361,7 @@ void FurnaceGUI::moveCursorPrevChannel(bool overflow) {
|
|||
}
|
||||
|
||||
void FurnaceGUI::moveCursorNextChannel(bool overflow) {
|
||||
makeCursorUndo();
|
||||
finishSelection();
|
||||
curNibble=false;
|
||||
|
||||
|
|
@ -382,6 +390,7 @@ void FurnaceGUI::moveCursorNextChannel(bool overflow) {
|
|||
}
|
||||
|
||||
void FurnaceGUI::moveCursorTop(bool select) {
|
||||
makeCursorUndo();
|
||||
if (!select) {
|
||||
finishSelection();
|
||||
}
|
||||
|
|
@ -403,6 +412,7 @@ void FurnaceGUI::moveCursorTop(bool select) {
|
|||
}
|
||||
|
||||
void FurnaceGUI::moveCursorBottom(bool select) {
|
||||
makeCursorUndo();
|
||||
if (!select) {
|
||||
finishSelection();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@
|
|||
#include "../engine/platform/pcmdac.h"
|
||||
#include "../engine/platform/k007232.h"
|
||||
#include "../engine/platform/ga20.h"
|
||||
#include "../engine/platform/supervision.h"
|
||||
#include "../engine/platform/sm8521.h"
|
||||
#include "../engine/platform/pv1000.h"
|
||||
#include "../engine/platform/k053260.h"
|
||||
|
|
|
|||
|
|
@ -731,6 +731,25 @@ void FurnaceGUI::drawDebug() {
|
|||
ImGui::Text("result: %.0f%%",realVol*100.0f);
|
||||
ImGui::TreePop();
|
||||
}
|
||||
if (ImGui::TreeNode("Cursor Undo Debug")) {
|
||||
auto DrawSpot=[&](const CursorJumpPoint& spot) {
|
||||
ImGui::Text("[%d:%d] <%d:%d, %d>", spot.subSong, spot.order, spot.point.xCoarse, spot.point.xFine, spot.point.y);
|
||||
};
|
||||
if (ImGui::BeginChild("##CursorUndoDebugChild", ImVec2(0, 300), true)) {
|
||||
if (ImGui::BeginTable("##CursorUndoDebug", 2, ImGuiTableFlags_Borders|ImGuiTableFlags_SizingStretchSame)) {
|
||||
for (size_t row=0; row<MAX(cursorUndoHist.size(),cursorRedoHist.size()); ++row) {
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
if (row<cursorUndoHist.size()) DrawSpot(cursorUndoHist[cursorUndoHist.size()-row-1]);
|
||||
ImGui::TableNextColumn();
|
||||
if (row<cursorRedoHist.size()) DrawSpot(cursorRedoHist[cursorRedoHist.size()-row-1]);
|
||||
}
|
||||
ImGui::EndTable();
|
||||
}
|
||||
}
|
||||
ImGui::EndChild();
|
||||
ImGui::TreePop();
|
||||
}
|
||||
if (ImGui::TreeNode("User Interface")) {
|
||||
if (ImGui::Button("Inspect")) {
|
||||
inspectorOpen=!inspectorOpen;
|
||||
|
|
|
|||
|
|
@ -680,10 +680,15 @@ void FurnaceGUI::doAction(int what) {
|
|||
latchTarget=0;
|
||||
latchNibble=false;
|
||||
break;
|
||||
case GUI_ACTION_PAT_ABSORB_INSTRUMENT: {
|
||||
case GUI_ACTION_PAT_ABSORB_INSTRUMENT:
|
||||
doAbsorbInstrument();
|
||||
break;
|
||||
}
|
||||
case GUI_ACTION_PAT_CURSOR_UNDO:
|
||||
doCursorUndo();
|
||||
break;
|
||||
case GUI_ACTION_PAT_CURSOR_REDO:
|
||||
doCursorRedo();
|
||||
break;
|
||||
|
||||
case GUI_ACTION_INS_LIST_ADD:
|
||||
if (settings.insTypeMenu) {
|
||||
|
|
|
|||
|
|
@ -678,6 +678,7 @@ void FurnaceGUI::doPasteFurnace(PasteMode mode, int arg, bool readClipboard, Str
|
|||
|
||||
if (readClipboard) {
|
||||
if (settings.cursorPastePos) {
|
||||
makeCursorUndo();
|
||||
cursor.y=j;
|
||||
if (cursor.y>=e->curSubSong->patLen) cursor.y=e->curSubSong->patLen-1;
|
||||
selStart=cursor;
|
||||
|
|
@ -1220,6 +1221,7 @@ void FurnaceGUI::doPasteMPT(PasteMode mode, int arg, bool readClipboard, String
|
|||
|
||||
if (readClipboard) {
|
||||
if (settings.cursorPastePos) {
|
||||
makeCursorUndo();
|
||||
cursor.y=j;
|
||||
if (cursor.y>=e->curSubSong->patLen) cursor.y=e->curSubSong->patLen-1;
|
||||
selStart=cursor;
|
||||
|
|
@ -1846,8 +1848,11 @@ void FurnaceGUI::doAbsorbInstrument() {
|
|||
}
|
||||
|
||||
// absorb most recent octave (i.e. set curOctave such that the "main row" (QWERTY) of
|
||||
// notes will result in an octave number equal to the previous note).
|
||||
if (!foundOctave && pat->data[i][0] != 0) {
|
||||
// notes will result in an octave number equal to the previous note). make sure to
|
||||
// skip "special note values" like OFF/REL/=== and "none", since there won't be valid
|
||||
// octave values
|
||||
unsigned char note=pat->data[i][0];
|
||||
if (!foundOctave && note!=0 && note!=100 && note!=101 && note!=102) {
|
||||
foundOctave=true;
|
||||
|
||||
// decode octave data (was signed cast to unsigned char)
|
||||
|
|
@ -2058,3 +2063,52 @@ void FurnaceGUI::doRedo() {
|
|||
|
||||
redoHist.pop_back();
|
||||
}
|
||||
|
||||
CursorJumpPoint FurnaceGUI::getCurrentCursorJumpPoint() {
|
||||
return CursorJumpPoint(cursor, curOrder, e->getCurrentSubSong());
|
||||
}
|
||||
|
||||
void FurnaceGUI::applyCursorJumpPoint(const CursorJumpPoint& spot) {
|
||||
cursor=spot.point;
|
||||
curOrder=MIN(e->curSubSong->ordersLen-1, spot.order);
|
||||
e->setOrder(curOrder);
|
||||
e->changeSongP(spot.subSong);
|
||||
if (!settings.cursorMoveNoScroll) {
|
||||
updateScroll(cursor.y);
|
||||
}
|
||||
}
|
||||
|
||||
void FurnaceGUI::makeCursorUndo() {
|
||||
CursorJumpPoint spot = getCurrentCursorJumpPoint();
|
||||
if (!cursorUndoHist.empty() && spot == cursorUndoHist.back()) return;
|
||||
|
||||
if (cursorUndoHist.size()>=settings.maxUndoSteps) cursorUndoHist.pop_front();
|
||||
cursorUndoHist.push_back(spot);
|
||||
|
||||
// redo history no longer relevant, we've changed timeline
|
||||
cursorRedoHist.clear();
|
||||
}
|
||||
|
||||
void FurnaceGUI::doCursorUndo() {
|
||||
if (cursorUndoHist.empty()) return;
|
||||
|
||||
// allow returning to current spot
|
||||
if (cursorRedoHist.size()>=settings.maxUndoSteps) cursorRedoHist.pop_front();
|
||||
cursorRedoHist.push_back(getCurrentCursorJumpPoint());
|
||||
|
||||
// apply spot
|
||||
applyCursorJumpPoint(cursorUndoHist.back());
|
||||
cursorUndoHist.pop_back();
|
||||
}
|
||||
|
||||
void FurnaceGUI::doCursorRedo() {
|
||||
if (cursorRedoHist.empty()) return;
|
||||
|
||||
// allow returning to current spot
|
||||
if (cursorUndoHist.size()>=settings.maxUndoSteps) cursorUndoHist.pop_front();
|
||||
cursorUndoHist.push_back(getCurrentCursorJumpPoint());
|
||||
|
||||
// apply spot
|
||||
applyCursorJumpPoint(cursorRedoHist.back());
|
||||
cursorRedoHist.pop_back();
|
||||
}
|
||||
|
|
@ -560,6 +560,7 @@ void FurnaceGUI::drawFindReplace() {
|
|||
if (ImGui::TableNextColumn()) {
|
||||
snprintf(tempID,1024,ICON_FA_CHEVRON_RIGHT "##_FR%d",index);
|
||||
if (ImGui::Selectable(tempID)) {
|
||||
makeCursorUndo();
|
||||
e->changeSongP(i.subsong);
|
||||
if (e->isPlaying()) {
|
||||
followPattern=false;
|
||||
|
|
|
|||
|
|
@ -388,6 +388,7 @@ void FurnaceGUI::decodeMMLStr(String& source, int* macro, unsigned char& macroLe
|
|||
setBit30=false;
|
||||
macroLen++;
|
||||
buf=0;
|
||||
MARK_MODIFIED;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -424,6 +425,21 @@ void FurnaceGUI::decodeMMLStr(String& source, int* macro, unsigned char& macroLe
|
|||
} \
|
||||
}
|
||||
|
||||
bool FurnaceGUI::isCtrlWheelModifierHeld() const {
|
||||
switch (settings.ctrlWheelModifier) {
|
||||
case 0:
|
||||
return ImGui::IsKeyDown(ImGuiMod_Ctrl) || ImGui::IsKeyDown(ImGuiMod_Super);
|
||||
case 1:
|
||||
return ImGui::IsKeyDown(ImGuiMod_Ctrl);
|
||||
case 2:
|
||||
return ImGui::IsKeyDown(ImGuiMod_Super);
|
||||
case 3:
|
||||
return ImGui::IsKeyDown(ImGuiMod_Alt);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool FurnaceGUI::CWSliderScalar(const char* label, ImGuiDataType data_type, void* p_data, const void* p_min, const void* p_max, const char* format, ImGuiSliderFlags flags) {
|
||||
flags^=ImGuiSliderFlags_AlwaysClamp;
|
||||
if (ImGui::SliderScalar(label,data_type,p_data,p_min,p_max,format,flags)) {
|
||||
|
|
@ -993,11 +1009,6 @@ Pos=339,177\n\
|
|||
Size=601,400\n\
|
||||
Collapsed=0\n\
|
||||
\n\
|
||||
[Window][Rendering...]\n\
|
||||
Pos=585,342\n\
|
||||
Size=600,100\n\
|
||||
Collapsed=0\n\
|
||||
\n\
|
||||
[Window][Export VGM##FileDialog]\n\
|
||||
Pos=340,177\n\
|
||||
Size=600,400\n\
|
||||
|
|
@ -1216,6 +1227,7 @@ void FurnaceGUI::play(int row) {
|
|||
memset(chanOscBright,0,DIV_MAX_CHANS*sizeof(float));
|
||||
e->walkSong(loopOrder,loopRow,loopEnd);
|
||||
memset(lastIns,-1,sizeof(int)*DIV_MAX_CHANS);
|
||||
if (followPattern) makeCursorUndo();
|
||||
if (!followPattern) e->setOrder(curOrder);
|
||||
if (row>0) {
|
||||
if (!e->playToRow(row)) {
|
||||
|
|
@ -5859,7 +5871,8 @@ bool FurnaceGUI::loop() {
|
|||
MEASURE_BEGIN(popup);
|
||||
|
||||
centerNextWindow(_("Rendering..."),canvasW,canvasH);
|
||||
if (ImGui::BeginPopupModal(_("Rendering..."),NULL,ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoMove)) {
|
||||
// ImGui::SetNextWindowSize(ImVec2(0.0f,0.0f));
|
||||
if (ImGui::BeginPopupModal(_("Rendering..."),NULL,ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoSavedSettings)) {
|
||||
// WHAT the HELL?!
|
||||
WAKE_UP;
|
||||
if (audioExportOptions.mode!=DIV_EXPORT_MODE_MANY_CHAN) {
|
||||
|
|
@ -5875,35 +5888,32 @@ bool FurnaceGUI::loop() {
|
|||
int curFile=0;
|
||||
int* curFileLambda=&curFile;
|
||||
if (e->isExporting()) {
|
||||
e->lockEngine([this, progressLambda, curPosInRowsLambda, curFileLambda,
|
||||
loopsLeftLambda, totalLoopsLambda] () {
|
||||
int curRow=0; int curOrder=0;
|
||||
e->getCurSongPos(curRow, curOrder); *curFileLambda=0;
|
||||
e->getCurFileIndex(*curFileLambda);
|
||||
*curPosInRowsLambda=curRow; for (int i=0; i<curOrder;
|
||||
i++) {
|
||||
*curPosInRowsLambda+=songOrdersLengths[i];}
|
||||
|
||||
if (!songHasSongEndCommand) {
|
||||
e->getLoopsLeft(*loopsLeftLambda); e->getTotalLoops(*totalLoopsLambda); if ((*totalLoopsLambda)!=(*loopsLeftLambda)) //we are going 2nd, 3rd, etc. time through the song
|
||||
{
|
||||
*curPosInRowsLambda-=(songLength-songLoopedSectionLength); //a hack so progress bar does not jump?
|
||||
}
|
||||
if (e->getIsFadingOut()) //we are in fadeout??? why it works like that bruh
|
||||
{
|
||||
// LIVE WITH IT damn it
|
||||
*curPosInRowsLambda-=(songLength-songLoopedSectionLength); //a hack so progress bar does not jump?
|
||||
}
|
||||
}
|
||||
// this horrible indentation courtesy of `indent`
|
||||
*progressLambda=(float) ((*curPosInRowsLambda) + ((*totalLoopsLambda)- (*loopsLeftLambda)) * songLength + lengthOfOneFile * (*curFileLambda)) / (float) totalLength;});
|
||||
e->lockEngine(
|
||||
[this, progressLambda, curPosInRowsLambda, curFileLambda, loopsLeftLambda, totalLoopsLambda] () {
|
||||
int curRow=0; int curOrder=0;
|
||||
e->getCurSongPos(curRow, curOrder);
|
||||
*curFileLambda=0;
|
||||
e->getCurFileIndex(*curFileLambda);
|
||||
*curPosInRowsLambda=curRow;
|
||||
for (int i=0; i<curOrder; i++) *curPosInRowsLambda+=songOrdersLengths[i];
|
||||
if (!songHasSongEndCommand) {
|
||||
e->getLoopsLeft(*loopsLeftLambda);
|
||||
e->getTotalLoops(*totalLoopsLambda);
|
||||
if ((*totalLoopsLambda)!=(*loopsLeftLambda)) { // we are going 2nd, 3rd, etc. time through the song
|
||||
*curPosInRowsLambda-=(songLength-songLoopedSectionLength); // a hack so progress bar does not jump?
|
||||
}
|
||||
if (e->getIsFadingOut()) { // we are in fadeout??? why it works like that bruh
|
||||
// LIVE WITH IT damn it
|
||||
*curPosInRowsLambda-=(songLength-songLoopedSectionLength); // a hack so progress bar does not jump?
|
||||
}
|
||||
}
|
||||
*progressLambda=(float)((*curPosInRowsLambda)+((*totalLoopsLambda)-(*loopsLeftLambda))*songLength+lengthOfOneFile*(*curFileLambda))/(float)totalLength;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
ImGui::Text(_("Row %d of %d"),curPosInRows+((totalLoops)-(loopsLeft))*songLength,lengthOfOneFile);
|
||||
|
||||
if (audioExportOptions.mode==DIV_EXPORT_MODE_MANY_CHAN) {
|
||||
ImGui::Text(_("Channel %d of %d"),curFile+1,totalFiles);
|
||||
}
|
||||
if (audioExportOptions.mode==DIV_EXPORT_MODE_MANY_CHAN) ImGui::Text(_("Channel %d of %d"),curFile+1,totalFiles);
|
||||
|
||||
ImGui::ProgressBar(curProgress,ImVec2(320.0f*dpiScale,0),fmt::sprintf("%.2f%%",curProgress*100.0f).c_str());
|
||||
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@
|
|||
#define FURNACE_APP_ID "org.tildearrow.furnace"
|
||||
|
||||
#define rightClickable if (ImGui::IsItemClicked(ImGuiMouseButton_Right)) ImGui::SetKeyboardFocusHere(-1);
|
||||
#define ctrlWheeling ((ImGui::IsKeyDown(ImGuiKey_LeftCtrl) || ImGui::IsKeyDown(ImGuiKey_RightCtrl)) && wheelY!=0)
|
||||
#define ctrlWheeling (isCtrlWheelModifierHeld() && wheelY!=0)
|
||||
|
||||
#define handleUnimportant if (settings.insFocusesPattern && patternOpen) {nextWindow=GUI_WINDOW_PATTERN;}
|
||||
#define unimportant(x) if (x) {handleUnimportant}
|
||||
|
|
@ -354,6 +354,8 @@ enum FurnaceGUIColors {
|
|||
GUI_COLOR_INSTR_GBA_MINMOD,
|
||||
GUI_COLOR_INSTR_BIFURCATOR,
|
||||
GUI_COLOR_INSTR_SID2,
|
||||
GUI_COLOR_INSTR_SUPERVISION,
|
||||
GUI_COLOR_INSTR_UPD1771C,
|
||||
GUI_COLOR_INSTR_SID3,
|
||||
GUI_COLOR_INSTR_UNKNOWN,
|
||||
|
||||
|
|
@ -819,6 +821,8 @@ enum FurnaceGUIActions {
|
|||
GUI_ACTION_PAT_SCROLL_MODE,
|
||||
GUI_ACTION_PAT_CLEAR_LATCH,
|
||||
GUI_ACTION_PAT_ABSORB_INSTRUMENT,
|
||||
GUI_ACTION_PAT_CURSOR_UNDO,
|
||||
GUI_ACTION_PAT_CURSOR_REDO,
|
||||
GUI_ACTION_PAT_MAX,
|
||||
|
||||
GUI_ACTION_INS_LIST_MIN,
|
||||
|
|
@ -1104,6 +1108,22 @@ struct UndoStep {
|
|||
newPatLen(0) {}
|
||||
};
|
||||
|
||||
struct CursorJumpPoint {
|
||||
SelectionPoint point;
|
||||
int order;
|
||||
int subSong;
|
||||
CursorJumpPoint(const SelectionPoint& p, int o, int ss):
|
||||
point(p), order(o), subSong(ss) {}
|
||||
CursorJumpPoint():
|
||||
point(), order(0), subSong(0) {}
|
||||
bool operator== (const CursorJumpPoint& spot) {
|
||||
return point.xCoarse==spot.point.xCoarse && point.xFine==spot.point.xFine && point.y==spot.point.y && order==spot.order && subSong==spot.subSong;
|
||||
}
|
||||
bool operator!= (const CursorJumpPoint& spot) {
|
||||
return !(*this == spot);
|
||||
}
|
||||
};
|
||||
|
||||
// -1 = any
|
||||
struct MIDIBind {
|
||||
int type, channel, data1, data2;
|
||||
|
|
@ -1753,6 +1773,7 @@ class FurnaceGUI {
|
|||
int opnbCore;
|
||||
int opl2Core;
|
||||
int opl3Core;
|
||||
int opl4Core;
|
||||
int esfmCore;
|
||||
int opllCore;
|
||||
int ayCore;
|
||||
|
|
@ -1779,6 +1800,7 @@ class FurnaceGUI {
|
|||
int opnbCoreRender;
|
||||
int opl2CoreRender;
|
||||
int opl3CoreRender;
|
||||
int opl4CoreRender;
|
||||
int esfmCoreRender;
|
||||
int opllCoreRender;
|
||||
int ayCoreRender;
|
||||
|
|
@ -1805,6 +1827,7 @@ class FurnaceGUI {
|
|||
int patRowsBase;
|
||||
int orderRowsBase;
|
||||
int soloAction;
|
||||
int ctrlWheelModifier;
|
||||
int pullDeleteBehavior;
|
||||
int wrapHorizontal;
|
||||
int wrapVertical;
|
||||
|
|
@ -2013,6 +2036,7 @@ class FurnaceGUI {
|
|||
opnbCore(1),
|
||||
opl2Core(0),
|
||||
opl3Core(0),
|
||||
opl4Core(0),
|
||||
esfmCore(0),
|
||||
opllCore(0),
|
||||
ayCore(0),
|
||||
|
|
@ -2039,6 +2063,7 @@ class FurnaceGUI {
|
|||
opnbCoreRender(1),
|
||||
opl2CoreRender(0),
|
||||
opl3CoreRender(0),
|
||||
opl4CoreRender(0),
|
||||
esfmCoreRender(0),
|
||||
opllCoreRender(0),
|
||||
ayCoreRender(0),
|
||||
|
|
@ -2064,6 +2089,7 @@ class FurnaceGUI {
|
|||
patRowsBase(0),
|
||||
orderRowsBase(1),
|
||||
soloAction(0),
|
||||
ctrlWheelModifier(0),
|
||||
pullDeleteBehavior(1),
|
||||
wrapHorizontal(0),
|
||||
wrapVertical(0),
|
||||
|
|
@ -2501,6 +2527,8 @@ class FurnaceGUI {
|
|||
std::map<unsigned short,DivPattern*> oldPatMap;
|
||||
FixedQueue<UndoStep,256> undoHist;
|
||||
FixedQueue<UndoStep,256> redoHist;
|
||||
FixedQueue<CursorJumpPoint,256> cursorUndoHist;
|
||||
FixedQueue<CursorJumpPoint,256> cursorRedoHist;
|
||||
|
||||
// sample editor specific
|
||||
double sampleZoom;
|
||||
|
|
@ -2741,6 +2769,7 @@ class FurnaceGUI {
|
|||
static bool LocalizedComboGetter(void* data, int idx, const char** out_text);
|
||||
|
||||
// these ones offer ctrl-wheel fine value changes.
|
||||
bool isCtrlWheelModifierHeld() const;
|
||||
bool CWSliderScalar(const char* label, ImGuiDataType data_type, void* p_data, const void* p_min, const void* p_max, const char* format=NULL, ImGuiSliderFlags flags=0);
|
||||
bool CWVSliderScalar(const char* label, const ImVec2& size, ImGuiDataType data_type, void* p_data, const void* p_min, const void* p_max, const char* format=NULL, ImGuiSliderFlags flags=0);
|
||||
bool CWSliderInt(const char* label, int* v, int v_min, int v_max, const char* format="%d", ImGuiSliderFlags flags=0);
|
||||
|
|
@ -2941,6 +2970,12 @@ class FurnaceGUI {
|
|||
|
||||
void doGenerateWave();
|
||||
|
||||
CursorJumpPoint getCurrentCursorJumpPoint();
|
||||
void applyCursorJumpPoint(const CursorJumpPoint& spot);
|
||||
void makeCursorUndo();
|
||||
void doCursorUndo();
|
||||
void doCursorRedo();
|
||||
|
||||
void doUndoSample();
|
||||
void doRedoSample();
|
||||
|
||||
|
|
|
|||
|
|
@ -184,6 +184,8 @@ const char* insTypes[DIV_INS_MAX+1][3]={
|
|||
{"GBA MinMod",ICON_FA_VOLUME_UP,ICON_FUR_INS_GBA_MINMOD},
|
||||
{"Bifurcator",ICON_FA_LINE_CHART,ICON_FUR_INS_BIFURCATOR},
|
||||
{"SID2",ICON_FA_KEYBOARD_O,ICON_FUR_INS_SID2},
|
||||
{"Watara Supervision",ICON_FA_GAMEPAD,ICON_FUR_INS_SUPERVISION},
|
||||
{"NEC μPD1771C",ICON_FA_BAR_CHART,ICON_FUR_INS_UPD1771C},
|
||||
{"SID3",ICON_FA_KEYBOARD_O,ICON_FUR_INS_SID3},
|
||||
{NULL,ICON_FA_QUESTION,ICON_FA_QUESTION}
|
||||
};
|
||||
|
|
@ -209,7 +211,7 @@ const char* sampleDepths[DIV_SAMPLE_DEPTH_MAX]={
|
|||
"8-bit µ-law PCM",
|
||||
"C219 PCM",
|
||||
"IMA ADPCM",
|
||||
NULL,
|
||||
"12-bit PCM",
|
||||
NULL,
|
||||
"16-bit PCM"
|
||||
};
|
||||
|
|
@ -689,6 +691,8 @@ const FurnaceGUIActionDef guiActions[GUI_ACTION_MAX]={
|
|||
D("PAT_SCROLL_MODE", _N("Change mobile scroll mode"), 0),
|
||||
D("PAT_CLEAR_LATCH", _N("Clear note input latch"), 0),
|
||||
D("PAT_ABSORB_INSTRUMENT", _N("Absorb instrument/octave from status at cursor"), 0),
|
||||
D("PAT_CURSOR_UNDO", _N("Return cursor to previous jump point"), 0),
|
||||
D("PAT_CURSOR_REDO", _N("Reverse recent cursor undo"), 0),
|
||||
D("PAT_MAX", "", NOT_AN_ACTION),
|
||||
|
||||
D("INS_LIST_MIN", _N("---Instrument list"), NOT_AN_ACTION),
|
||||
|
|
@ -1017,6 +1021,8 @@ const FurnaceGUIColorDef guiColors[GUI_COLOR_MAX]={
|
|||
D(GUI_COLOR_INSTR_GBA_MINMOD,"",ImVec4(0.5f,0.45f,0.7f,1.0f)),
|
||||
D(GUI_COLOR_INSTR_BIFURCATOR,"",ImVec4(0.8925f,0.8925f,0.8925f,1.0f)),
|
||||
D(GUI_COLOR_INSTR_SID2,"",ImVec4(0.6f,0.75f,1.0f,1.0f)),
|
||||
D(GUI_COLOR_INSTR_SUPERVISION,"",ImVec4(0.52f,1.0f,0.6f,1.0f)),
|
||||
D(GUI_COLOR_INSTR_UPD1771C,"",ImVec4(0.94f,0.52f,0.6f,1.0f)),
|
||||
D(GUI_COLOR_INSTR_SID3,"",ImVec4(0.6f,0.75f,0.6f,1.0f)),
|
||||
D(GUI_COLOR_INSTR_UNKNOWN,"",ImVec4(0.3f,0.3f,0.3f,1.0f)),
|
||||
|
||||
|
|
@ -1266,6 +1272,10 @@ const int availableSystems[]={
|
|||
DIV_SYSTEM_5E01,
|
||||
DIV_SYSTEM_BIFURCATOR,
|
||||
DIV_SYSTEM_SID2,
|
||||
DIV_SYSTEM_OPL4,
|
||||
DIV_SYSTEM_OPL4_DRUMS,
|
||||
DIV_SYSTEM_SUPERVISION,
|
||||
DIV_SYSTEM_UPD1771C,
|
||||
DIV_SYSTEM_SID3,
|
||||
0 // don't remove this last one!
|
||||
};
|
||||
|
|
@ -1302,6 +1312,8 @@ const int chipsFM[]={
|
|||
DIV_SYSTEM_OPL3_DRUMS,
|
||||
DIV_SYSTEM_OPZ,
|
||||
DIV_SYSTEM_ESFM,
|
||||
DIV_SYSTEM_OPL4,
|
||||
DIV_SYSTEM_OPL4_DRUMS,
|
||||
0 // don't remove this last one!
|
||||
};
|
||||
|
||||
|
|
@ -1362,6 +1374,8 @@ const int chipsSpecial[]={
|
|||
DIV_SYSTEM_5E01,
|
||||
DIV_SYSTEM_BIFURCATOR,
|
||||
DIV_SYSTEM_SID2,
|
||||
DIV_SYSTEM_SUPERVISION,
|
||||
DIV_SYSTEM_UPD1771C,
|
||||
DIV_SYSTEM_SID3,
|
||||
0 // don't remove this last one!
|
||||
};
|
||||
|
|
@ -1388,6 +1402,8 @@ const int chipsSample[]={
|
|||
DIV_SYSTEM_NDS,
|
||||
DIV_SYSTEM_GBA_DMA,
|
||||
DIV_SYSTEM_GBA_MINMOD,
|
||||
DIV_SYSTEM_OPL4,
|
||||
DIV_SYSTEM_OPL4_DRUMS,
|
||||
0 // don't remove this last one!
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -2746,48 +2746,68 @@ void FurnaceGUI::drawMacros(std::vector<FurnaceGUIMacroDesc>& macros, FurnaceGUI
|
|||
drawMacroEdit(m,totalFit,availableWidth,index);
|
||||
|
||||
if (m.macro->open&1) {
|
||||
if ((m.macro->open&6)==0) {
|
||||
ImGui::Text(_("Length"));
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(120.0f*dpiScale);
|
||||
int macroLen=m.macro->len;
|
||||
if (ImGui::InputScalar("##IMacroLen",ImGuiDataType_U8,¯oLen,&_ONE,&_THREE)) { MARK_MODIFIED
|
||||
if (macroLen<0) macroLen=0;
|
||||
if (macroLen>255) macroLen=255;
|
||||
m.macro->len=macroLen;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
}
|
||||
ImGui::Text(_("StepLen"));
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(120.0f*dpiScale);
|
||||
if (ImGui::InputScalar("##IMacroSpeed",ImGuiDataType_U8,&m.macro->speed,&_ONE,&_THREE)) {
|
||||
if (m.macro->speed<1) m.macro->speed=1;
|
||||
MARK_MODIFIED;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::Text(_("Delay"));
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(120.0f*dpiScale);
|
||||
if (ImGui::InputScalar("##IMacroDelay",ImGuiDataType_U8,&m.macro->delay,&_ONE,&_THREE)) {
|
||||
MARK_MODIFIED;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
{
|
||||
FurnaceGUIMacroDesc& i=m;
|
||||
BUTTON_TO_SET_MODE(ImGui::Button);
|
||||
if ((i.macro->open&6)==0) {
|
||||
bool showLen=((m.macro->open&6)==0);
|
||||
int colCount=showLen ? 4 : 3;
|
||||
float availX=ImGui::GetContentRegionAvail().x;
|
||||
|
||||
// fairly arbitrary scaling logic
|
||||
bool shortLabels=(availX<600.0f*dpiScale);
|
||||
float scalarItemWidth=MIN((availX-90.0f*dpiScale)/colCount, 120.0f*dpiScale);
|
||||
if (ImGui::BeginTable("##MacroMetaData",colCount)) {
|
||||
if (showLen) ImGui::TableSetupColumn("len",ImGuiTableColumnFlags_WidthStretch,0.0);
|
||||
ImGui::TableSetupColumn("stepLen",ImGuiTableColumnFlags_WidthStretch,0.0);
|
||||
ImGui::TableSetupColumn("delay",ImGuiTableColumnFlags_WidthStretch,0.0);
|
||||
ImGui::TableSetupColumn("buttons",ImGuiTableColumnFlags_WidthFixed,0.0);
|
||||
|
||||
ImGui::TableNextRow();
|
||||
if (showLen) {
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text(shortLabels ? _("Len##macroEditLengthShortLabel") : _("Length"));
|
||||
if (shortLabels && ImGui::IsItemHovered()) ImGui::SetTooltip("%s", _("Length"));
|
||||
ImGui::SameLine();
|
||||
BUTTON_TO_SET_RELEASE(ImGui::Button);
|
||||
ImGui::SetNextItemWidth(scalarItemWidth);
|
||||
int macroLen=m.macro->len;
|
||||
if (ImGui::InputScalar("##IMacroLen",ImGuiDataType_U8,¯oLen,&_ONE,&_THREE)) { MARK_MODIFIED
|
||||
if (macroLen<0) macroLen=0;
|
||||
if (macroLen>255) macroLen=255;
|
||||
m.macro->len=macroLen;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m.modeName!=NULL) {
|
||||
bool modeVal=m.macro->mode;
|
||||
String modeName=fmt::sprintf("%s##IMacroMode",m.modeName);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text(shortLabels ? _("SLen##macroEditStepLenShortLabel") : _("StepLen"));
|
||||
if (shortLabels && ImGui::IsItemHovered()) ImGui::SetTooltip("%s", _("StepLen"));
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Checkbox(modeName.c_str(),&modeVal)) {
|
||||
m.macro->mode=modeVal;
|
||||
ImGui::SetNextItemWidth(scalarItemWidth);
|
||||
if (ImGui::InputScalar("##IMacroSpeed",ImGuiDataType_U8,&m.macro->speed,&_ONE,&_THREE)) {
|
||||
if (m.macro->speed<1) m.macro->speed=1;
|
||||
MARK_MODIFIED;
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text(shortLabels ? _("Del##macroEditDelayShortLabel") : _("Delay"));
|
||||
if (shortLabels && ImGui::IsItemHovered()) ImGui::SetTooltip("%s", _("Delay"));
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(scalarItemWidth);
|
||||
if (ImGui::InputScalar("##IMacroDelay",ImGuiDataType_U8,&m.macro->delay,&_ONE,&_THREE)) {
|
||||
MARK_MODIFIED;
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
{
|
||||
FurnaceGUIMacroDesc& i=m;
|
||||
BUTTON_TO_SET_MODE(ImGui::Button);
|
||||
if ((i.macro->open&6)==0) {
|
||||
ImGui::SameLine();
|
||||
BUTTON_TO_SET_RELEASE(ImGui::Button);
|
||||
}
|
||||
}
|
||||
if (m.modeName!=NULL) {
|
||||
bool modeVal=m.macro->mode;
|
||||
String modeName=fmt::sprintf("%s##IMacroMode",m.modeName);
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Checkbox(modeName.c_str(),&modeVal)) {
|
||||
m.macro->mode=modeVal;
|
||||
}
|
||||
}
|
||||
ImGui::EndTable();
|
||||
}
|
||||
} else {
|
||||
ImGui::Text(_("The heck? No, this isn't even working correctly..."));
|
||||
|
|
@ -3289,6 +3309,7 @@ void FurnaceGUI::insTabSample(DivInstrument* ins) {
|
|||
ins->type==DIV_INS_VRC6 ||
|
||||
ins->type==DIV_INS_SU ||
|
||||
ins->type==DIV_INS_NDS ||
|
||||
ins->type==DIV_INS_SUPERVISION ||
|
||||
ins->type==DIV_INS_SID3) {
|
||||
P(ImGui::Checkbox(_("Use sample"),&ins->amiga.useSample));
|
||||
if (ins->type==DIV_INS_X1_010) {
|
||||
|
|
@ -4120,8 +4141,8 @@ void FurnaceGUI::insTabFM(DivInstrument* ins) {
|
|||
|
||||
opllPreview.alg=ins->fm.alg;
|
||||
opllPreview.fb=patch->fb;
|
||||
opllPreview.fms=patch->dm;
|
||||
opllPreview.ams=patch->dc;
|
||||
opllPreview.fms=patch->dc;
|
||||
opllPreview.ams=patch->dm;
|
||||
|
||||
opllPreview.op[0].tl=patch->tl;
|
||||
opllPreview.op[1].tl=ins->fm.op[1].tl;
|
||||
|
|
@ -4131,6 +4152,7 @@ void FurnaceGUI::insTabFM(DivInstrument* ins) {
|
|||
opllPreview.op[i].vib=patch->vib[i];
|
||||
opllPreview.op[i].ssgEnv=patch->et[i]?8:0;
|
||||
opllPreview.op[i].ksr=patch->ksr[i];
|
||||
opllPreview.op[i].ksl=patch->ksl[i];
|
||||
opllPreview.op[i].mult=patch->multi[i];
|
||||
opllPreview.op[i].ar=patch->ar[i];
|
||||
opllPreview.op[i].dr=patch->dr[i];
|
||||
|
|
@ -4650,7 +4672,7 @@ void FurnaceGUI::insTabFM(DivInstrument* ins) {
|
|||
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)"));
|
||||
ImGui::SetTooltip(_("OPL2/3/4 only (last 4 waveforms are OPL3/4 only)"));
|
||||
}
|
||||
if (ins->type==DIV_INS_ESFM && fixedOn) {
|
||||
if (ImGui::Checkbox(FM_SHORT_NAME(FM_VIB),&vibOn)) { PARAMETER
|
||||
|
|
@ -5014,7 +5036,7 @@ void FurnaceGUI::insTabFM(DivInstrument* ins) {
|
|||
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)"));
|
||||
ImGui::SetTooltip(_("OPL2/3/4 only (last 4 waveforms are OPL3/4 only)"));
|
||||
}
|
||||
|
||||
// params
|
||||
|
|
@ -5064,7 +5086,7 @@ void FurnaceGUI::insTabFM(DivInstrument* ins) {
|
|||
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)"));
|
||||
ImGui::SetTooltip(_("OPL2/3/4 only (last 4 waveforms are OPL3/4 only)"));
|
||||
}
|
||||
|
||||
// params
|
||||
|
|
@ -5772,7 +5794,7 @@ void FurnaceGUI::insTabFM(DivInstrument* ins) {
|
|||
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)"));
|
||||
ImGui::SetTooltip(_("OPL2/3/4 only (last 4 waveforms are OPL3/4 only)"));
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%s",FM_NAME(FM_WS));
|
||||
|
|
@ -7475,7 +7497,8 @@ void FurnaceGUI::drawInsEdit() {
|
|||
ins->type==DIV_INS_C219 ||
|
||||
ins->type==DIV_INS_NDS ||
|
||||
ins->type==DIV_INS_GBA_DMA ||
|
||||
ins->type==DIV_INS_GBA_MINMOD) {
|
||||
ins->type==DIV_INS_GBA_MINMOD ||
|
||||
ins->type==DIV_INS_SUPERVISION) {
|
||||
insTabSample(ins);
|
||||
}
|
||||
if (ins->type==DIV_INS_N163) if (ImGui::BeginTabItem("Namco 163")) {
|
||||
|
|
@ -7789,6 +7812,19 @@ void FurnaceGUI::drawInsEdit() {
|
|||
P(CWSliderScalar(_("AM Depth"),ImGuiDataType_U8,&ins->multipcm.am,&_ZERO,&_SEVEN)); rightClickable
|
||||
ImGui::EndTable();
|
||||
}
|
||||
P(ImGui::Checkbox(_("Damp"),&ins->multipcm.damp));
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip(_("Only for OPL4 PCM."));
|
||||
}
|
||||
P(ImGui::Checkbox(_("Pseudo Reverb"),&ins->multipcm.pseudoReverb));
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip(_("Only for OPL4 PCM."));
|
||||
}
|
||||
P(ImGui::Checkbox(_("LFO Reset"),&ins->multipcm.lfoReset));
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip(_("Only for OPL4 PCM."));
|
||||
}
|
||||
P(ImGui::Checkbox(_("Level Direct"),&ins->multipcm.levelDirect));
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
}
|
||||
|
|
@ -8225,6 +8261,9 @@ void FurnaceGUI::drawInsEdit() {
|
|||
macroList.push_back(FurnaceGUIMacroDesc(_("Panning"),&ins->std.panLMacro,-7,7,45,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL));
|
||||
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
|
||||
macroList.push_back(FurnaceGUIMacroDesc(_("Phase Reset"),&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
|
||||
macroList.push_back(FurnaceGUIMacroDesc(_("LFO Speed"),&ins->std.ex1Macro,0,7,160,uiColors[GUI_COLOR_MACRO_OTHER]));
|
||||
macroList.push_back(FurnaceGUIMacroDesc(_("LFO Vib Depth"),&ins->std.fmsMacro,0,7,160,uiColors[GUI_COLOR_MACRO_PITCH]));
|
||||
macroList.push_back(FurnaceGUIMacroDesc(_("LFO AM Depth"),&ins->std.amsMacro,0,7,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
|
||||
break;
|
||||
case DIV_INS_SNES:
|
||||
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,127,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
|
||||
|
|
@ -8376,6 +8415,13 @@ void FurnaceGUI::drawInsEdit() {
|
|||
macroList.push_back(FurnaceGUIMacroDesc(_("Pulse Width"),&ins->std.dutyMacro,0,255,160,uiColors[GUI_COLOR_MACRO_OTHER]));
|
||||
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
|
||||
break;
|
||||
case DIV_INS_SUPERVISION:
|
||||
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
|
||||
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
|
||||
macroList.push_back(FurnaceGUIMacroDesc(_("Duty/Noise"),&ins->std.dutyMacro,0,3,160,uiColors[GUI_COLOR_MACRO_NOISE]));
|
||||
macroList.push_back(FurnaceGUIMacroDesc(_("Noise/PCM Pan"),&ins->std.panLMacro,0,2,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,panBits));
|
||||
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
|
||||
break;
|
||||
case DIV_INS_SM8521:
|
||||
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,31,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
|
||||
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
|
||||
|
|
@ -8518,8 +8564,17 @@ void FurnaceGUI::drawInsEdit() {
|
|||
macroList.push_back(FurnaceGUIMacroDesc(_("Noise Mode"),&ins->std.fmsMacro,0,3,64,uiColors[GUI_COLOR_MACRO_NOISE]));
|
||||
macroList.push_back(FurnaceGUIMacroDesc(_("Wave Mix"),&ins->std.amsMacro,0,3,64,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,macroSID2WaveMixMode));
|
||||
break;
|
||||
case DIV_INS_SID3: break;
|
||||
|
||||
case DIV_INS_UPD1771C:
|
||||
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,31,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
|
||||
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
|
||||
macroList.push_back(FurnaceGUIMacroDesc(_("Waveform"),&ins->std.waveMacro,0,7,160,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,NULL,false,NULL));
|
||||
macroList.push_back(FurnaceGUIMacroDesc(_("Wave Pos"),&ins->std.ex1Macro,0,31,160,uiColors[GUI_COLOR_MACRO_OTHER]));
|
||||
macroList.push_back(FurnaceGUIMacroDesc(_("Duty/Mode"),&ins->std.dutyMacro,0,1,160,uiColors[GUI_COLOR_MACRO_NOISE]));
|
||||
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
|
||||
break;
|
||||
case DIV_INS_SID3:
|
||||
// TODO: put stuff here to kill that goto.
|
||||
break;
|
||||
case DIV_INS_MAX:
|
||||
case DIV_INS_NULL:
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -320,6 +320,11 @@ void FurnaceGUI::initSystemPresets() {
|
|||
CH(DIV_SYSTEM_NDS, 1.0f, 0, "")
|
||||
}
|
||||
);
|
||||
ENTRY(
|
||||
"Watara Supervision", {
|
||||
CH(DIV_SYSTEM_SUPERVISION, 1.0f, 0, "")
|
||||
}
|
||||
);
|
||||
CATEGORY_END;
|
||||
|
||||
CATEGORY_BEGIN(_("Computers"),_("let's get to work on chiptune today."));
|
||||
|
|
@ -519,6 +524,18 @@ void FurnaceGUI::initSystemPresets() {
|
|||
) // variable rate, Mono DAC
|
||||
}
|
||||
);
|
||||
SUB_ENTRY(
|
||||
"MSX + MoonSound", {
|
||||
CH(DIV_SYSTEM_AY8910, 1.0f, 0, "chipType=1"),
|
||||
CH(DIV_SYSTEM_OPL4, 1.0f, 0, "")
|
||||
}
|
||||
);
|
||||
SUB_ENTRY(
|
||||
"MSX + MoonSound (drums mode)", {
|
||||
CH(DIV_SYSTEM_AY8910, 1.0f, 0, "chipType=1"),
|
||||
CH(DIV_SYSTEM_OPL4_DRUMS, 1.0f, 0, "")
|
||||
}
|
||||
);
|
||||
ENTRY(
|
||||
_("NEC PC-6001"), {
|
||||
CH(DIV_SYSTEM_AY8910, 1.0f, 0, "customClock=3993600")
|
||||
|
|
@ -1319,6 +1336,11 @@ void FurnaceGUI::initSystemPresets() {
|
|||
)
|
||||
}
|
||||
);
|
||||
ENTRY(
|
||||
"Epoch Super Cassette Vision", {
|
||||
CH(DIV_SYSTEM_UPD1771C, 1.0f, 0, "")
|
||||
}
|
||||
);
|
||||
CATEGORY_END;
|
||||
|
||||
CATEGORY_BEGIN(_("Arcade systems"),_("INSERT COIN"));
|
||||
|
|
@ -1895,6 +1917,30 @@ void FurnaceGUI::initSystemPresets() {
|
|||
}
|
||||
);
|
||||
|
||||
ENTRY(
|
||||
_("Psikyo"), {}
|
||||
);
|
||||
SUB_ENTRY(
|
||||
_("Psikyo 68EC020 hardware with OPL4"), {
|
||||
CH(DIV_SYSTEM_OPL4, 1.0f, 0, "")
|
||||
}
|
||||
);
|
||||
SUB_ENTRY(
|
||||
_("Psikyo 68EC020 hardware with OPL4 (drums mode)"), {
|
||||
CH(DIV_SYSTEM_OPL4_DRUMS, 1.0f, 0, "")
|
||||
}
|
||||
);
|
||||
SUB_ENTRY(
|
||||
_("Psikyo SH-2 hardware"), {
|
||||
CH(DIV_SYSTEM_OPL4, 1.0f, 0, "clockSel=1")
|
||||
}
|
||||
);
|
||||
SUB_ENTRY(
|
||||
_("Psikyo SH-2 hardware (drums mode)"), {
|
||||
CH(DIV_SYSTEM_OPL4_DRUMS, 1.0f, 0, "clockSel=1")
|
||||
}
|
||||
);
|
||||
|
||||
ENTRY(
|
||||
_("Sega"), {}
|
||||
);
|
||||
|
|
@ -2719,6 +2765,16 @@ void FurnaceGUI::initSystemPresets() {
|
|||
CH(DIV_SYSTEM_ESFM, 1.0f, 0, "")
|
||||
}
|
||||
);
|
||||
ENTRY(
|
||||
"Yamaha YMF278B (OPL4)", {
|
||||
CH(DIV_SYSTEM_OPL4, 1.0f, 0, "")
|
||||
}
|
||||
);
|
||||
SUB_ENTRY(
|
||||
"Yamaha YMF278B (drums mode)", {
|
||||
CH(DIV_SYSTEM_OPL4_DRUMS, 1.0f, 0, "")
|
||||
}
|
||||
);
|
||||
if (settings.hiddenSystems) {
|
||||
ENTRY(
|
||||
_("Yamaha YMU759 (MA-2)"), {
|
||||
|
|
@ -2930,6 +2986,16 @@ void FurnaceGUI::initSystemPresets() {
|
|||
CH(DIV_SYSTEM_NDS, 1.0f, 0, "")
|
||||
}
|
||||
);
|
||||
ENTRY(
|
||||
"Yamaha YMF278B (OPL4)", {
|
||||
CH(DIV_SYSTEM_OPL4, 1.0f, 0, "")
|
||||
}
|
||||
);
|
||||
SUB_ENTRY(
|
||||
"Yamaha YMF278B (drums mode)", {
|
||||
CH(DIV_SYSTEM_OPL4_DRUMS, 1.0f, 0, "")
|
||||
}
|
||||
);
|
||||
CATEGORY_END;
|
||||
|
||||
CATEGORY_BEGIN(_("Wavetable"),_("chips which use user-specified waveforms to generate sound."));
|
||||
|
|
@ -3125,6 +3191,16 @@ void FurnaceGUI::initSystemPresets() {
|
|||
CH(DIV_SYSTEM_SID3, 1.0f, 0, "")
|
||||
}
|
||||
);
|
||||
ENTRY(
|
||||
_("Watara Supervision"), {
|
||||
CH(DIV_SYSTEM_SUPERVISION, 1.0f, 0, "")
|
||||
}
|
||||
);
|
||||
ENTRY(
|
||||
_("NEC μPD1771C"), {
|
||||
CH(DIV_SYSTEM_UPD1771C, 1.0f, 0, "")
|
||||
}
|
||||
);
|
||||
CATEGORY_END;
|
||||
|
||||
CATEGORY_BEGIN(_("DefleMask-compatible"),_("these configurations are compatible with DefleMask.\nselect this if you need to save as .dmf or work with that program."));
|
||||
|
|
|
|||
|
|
@ -413,6 +413,25 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
SAMPLE_WARN(warnLength,_("GBA DMA: sample length will be padded to multiple of 16"));
|
||||
}
|
||||
break;
|
||||
case DIV_SYSTEM_OPL4:
|
||||
case DIV_SYSTEM_OPL4_DRUMS:
|
||||
if (sample->samples>65535) {
|
||||
SAMPLE_WARN(warnLength,_("OPL4: maximum sample length is 65535"));
|
||||
}
|
||||
break;
|
||||
case DIV_SYSTEM_SUPERVISION:
|
||||
if (sample->loop) {
|
||||
if (sample->loopStart!=0 || sample->loopEnd!=(int)(sample->samples)) {
|
||||
SAMPLE_WARN(warnLoopPos,_("Supervision: loop point ignored on sample channel"));
|
||||
}
|
||||
}
|
||||
if (sample->samples&31) {
|
||||
SAMPLE_WARN(warnLength,_("Supervision: sample length will be padded to multiple of 32"));
|
||||
}
|
||||
if (sample->samples>8192) {
|
||||
SAMPLE_WARN(warnLength,_("Supervision: maximum sample length is 8192"));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -189,6 +189,11 @@ const char* opl3Cores[]={
|
|||
"YMF262-LLE"
|
||||
};
|
||||
|
||||
const char* opl4Cores[]={
|
||||
"Nuked-OPL3 (FM) + openMSX (PCM)",
|
||||
"ymfm"
|
||||
};
|
||||
|
||||
const char* esfmCores[]={
|
||||
"ESFMu",
|
||||
_N("ESFMu (fast)")
|
||||
|
|
@ -2058,6 +2063,17 @@ void FurnaceGUI::drawSettings() {
|
|||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
if (ImGui::Combo("##OPL3CoreRender",&settings.opl3CoreRender,opl3Cores,3)) settingsChanged=true;
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::Text("OPL4");
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
if (ImGui::Combo("##OPL4Core",&settings.opl4Core,opl4Cores,2)) settingsChanged=true;
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
if (ImGui::Combo("##OPL4CoreRender",&settings.opl4CoreRender,opl4Cores,2)) settingsChanged=true;
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::AlignTextToFramePadding();
|
||||
|
|
@ -2137,7 +2153,6 @@ void FurnaceGUI::drawSettings() {
|
|||
ImGui::SameLine();
|
||||
if (ImGui::Combo("##PCSOutMethod",&settings.pcSpeakerOutMethod,LocalizedComboGetter,pcspkrOutMethods,5)) settingsChanged=true;
|
||||
|
||||
/*
|
||||
ImGui::Separator();
|
||||
ImGui::Text(_("Sample ROMs:"));
|
||||
|
||||
|
|
@ -2150,6 +2165,7 @@ void FurnaceGUI::drawSettings() {
|
|||
openFileDialog(GUI_FILE_YRW801_ROM_OPEN);
|
||||
}
|
||||
|
||||
/*
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::Text(_("MultiPCM TG100 path"));
|
||||
ImGui::SameLine();
|
||||
|
|
@ -2428,6 +2444,8 @@ void FurnaceGUI::drawSettings() {
|
|||
UI_KEYBIND_CONFIG(GUI_ACTION_PAT_LATCH);
|
||||
UI_KEYBIND_CONFIG(GUI_ACTION_PAT_CLEAR_LATCH);
|
||||
UI_KEYBIND_CONFIG(GUI_ACTION_PAT_ABSORB_INSTRUMENT);
|
||||
UI_KEYBIND_CONFIG(GUI_ACTION_PAT_CURSOR_UNDO);
|
||||
UI_KEYBIND_CONFIG(GUI_ACTION_PAT_CURSOR_REDO);
|
||||
|
||||
KEYBIND_CONFIG_END;
|
||||
ImGui::TreePop();
|
||||
|
|
@ -2720,6 +2738,27 @@ void FurnaceGUI::drawSettings() {
|
|||
}
|
||||
ImGui::Unindent();
|
||||
|
||||
ImGui::Text(_("Modifier for alternate wheel-scrolling (vertical/zoom/slider-input):"));
|
||||
ImGui::Indent();
|
||||
if (ImGui::RadioButton(_("Ctrl or Meta/Cmd##cwm1"),settings.ctrlWheelModifier==0)) {
|
||||
settings.ctrlWheelModifier=0;
|
||||
settingsChanged=true;
|
||||
}
|
||||
if (ImGui::RadioButton(_("Ctrl##cwm2"),settings.ctrlWheelModifier==1)) {
|
||||
settings.ctrlWheelModifier=1;
|
||||
settingsChanged=true;
|
||||
}
|
||||
if (ImGui::RadioButton(_("Meta/Cmd##cwm3"),settings.ctrlWheelModifier==2)) {
|
||||
settings.ctrlWheelModifier=2;
|
||||
settingsChanged=true;
|
||||
}
|
||||
// technically this key is called Option on mac, but we call it Alt in getKeyName(s)
|
||||
if (ImGui::RadioButton(_("Alt##cwm4"),settings.ctrlWheelModifier==3)) {
|
||||
settings.ctrlWheelModifier=3;
|
||||
settingsChanged=true;
|
||||
}
|
||||
ImGui::Unindent();
|
||||
|
||||
bool doubleClickColumnB=settings.doubleClickColumn;
|
||||
if (ImGui::Checkbox(_("Double click selects entire column"),&doubleClickColumnB)) {
|
||||
settings.doubleClickColumn=doubleClickColumnB;
|
||||
|
|
@ -4126,6 +4165,8 @@ void FurnaceGUI::drawSettings() {
|
|||
UI_COLOR_CONFIG(GUI_COLOR_INSTR_GBA_MINMOD,_("GBA MinMod"));
|
||||
UI_COLOR_CONFIG(GUI_COLOR_INSTR_BIFURCATOR,_("Bifurcator"));
|
||||
UI_COLOR_CONFIG(GUI_COLOR_INSTR_SID2,_("SID2"));
|
||||
UI_COLOR_CONFIG(GUI_COLOR_INSTR_SUPERVISION,_("Supervision"));
|
||||
UI_COLOR_CONFIG(GUI_COLOR_INSTR_UPD1771C,_("μPD1771C"));
|
||||
UI_COLOR_CONFIG(GUI_COLOR_INSTR_SID3,_("SID3"));
|
||||
UI_COLOR_CONFIG(GUI_COLOR_INSTR_UNKNOWN,_("Other/Unknown"));
|
||||
ImGui::TreePop();
|
||||
|
|
@ -4820,6 +4861,7 @@ void FurnaceGUI::readConfig(DivConfig& conf, FurnaceGUISettingGroups groups) {
|
|||
|
||||
if (groups&GUI_SETTINGS_BEHAVIOR) {
|
||||
settings.soloAction=conf.getInt("soloAction",0);
|
||||
settings.ctrlWheelModifier=conf.getInt("ctrlWheelModifier",0);
|
||||
settings.pullDeleteBehavior=conf.getInt("pullDeleteBehavior",1);
|
||||
settings.wrapHorizontal=conf.getInt("wrapHorizontal",0);
|
||||
settings.wrapVertical=conf.getInt("wrapVertical",0);
|
||||
|
|
@ -4999,6 +5041,7 @@ void FurnaceGUI::readConfig(DivConfig& conf, FurnaceGUISettingGroups groups) {
|
|||
settings.opnbCore=conf.getInt("opnbCore",1);
|
||||
settings.opl2Core=conf.getInt("opl2Core",0);
|
||||
settings.opl3Core=conf.getInt("opl3Core",0);
|
||||
settings.opl4Core=conf.getInt("opl4Core",0);
|
||||
settings.esfmCore=conf.getInt("esfmCore",0);
|
||||
settings.opllCore=conf.getInt("opllCore",0);
|
||||
settings.ayCore=conf.getInt("ayCore",0);
|
||||
|
|
@ -5027,6 +5070,7 @@ void FurnaceGUI::readConfig(DivConfig& conf, FurnaceGUISettingGroups groups) {
|
|||
settings.opnbCoreRender=conf.getInt("opnbCoreRender",1);
|
||||
settings.opl2CoreRender=conf.getInt("opl2CoreRender",0);
|
||||
settings.opl3CoreRender=conf.getInt("opl3CoreRender",0);
|
||||
settings.opl4CoreRender=conf.getInt("opl4CoreRender",0);
|
||||
settings.esfmCoreRender=conf.getInt("esfmCoreRender",0);
|
||||
settings.opllCoreRender=conf.getInt("opllCoreRender",0);
|
||||
settings.ayCoreRender=conf.getInt("ayCoreRender",0);
|
||||
|
|
@ -5072,6 +5116,7 @@ void FurnaceGUI::readConfig(DivConfig& conf, FurnaceGUISettingGroups groups) {
|
|||
clampSetting(settings.opnbCore,0,2);
|
||||
clampSetting(settings.opl2Core,0,2);
|
||||
clampSetting(settings.opl3Core,0,2);
|
||||
clampSetting(settings.opl4Core,0,1);
|
||||
clampSetting(settings.esfmCore,0,1);
|
||||
clampSetting(settings.opllCore,0,1);
|
||||
clampSetting(settings.ayCore,0,1);
|
||||
|
|
@ -5098,6 +5143,7 @@ void FurnaceGUI::readConfig(DivConfig& conf, FurnaceGUISettingGroups groups) {
|
|||
clampSetting(settings.opnbCoreRender,0,2);
|
||||
clampSetting(settings.opl2CoreRender,0,2);
|
||||
clampSetting(settings.opl3CoreRender,0,2);
|
||||
clampSetting(settings.opl4CoreRender,0,1);
|
||||
clampSetting(settings.esfmCoreRender,0,1);
|
||||
clampSetting(settings.opllCoreRender,0,1);
|
||||
clampSetting(settings.ayCoreRender,0,1);
|
||||
|
|
@ -5118,6 +5164,7 @@ void FurnaceGUI::readConfig(DivConfig& conf, FurnaceGUISettingGroups groups) {
|
|||
clampSetting(settings.patRowsBase,0,1);
|
||||
clampSetting(settings.orderRowsBase,0,1);
|
||||
clampSetting(settings.soloAction,0,2);
|
||||
clampSetting(settings.ctrlWheelModifier,0,3);
|
||||
clampSetting(settings.pullDeleteBehavior,0,1);
|
||||
clampSetting(settings.wrapHorizontal,0,2);
|
||||
clampSetting(settings.wrapVertical,0,3);
|
||||
|
|
@ -5405,6 +5452,7 @@ void FurnaceGUI::writeConfig(DivConfig& conf, FurnaceGUISettingGroups groups) {
|
|||
// behavior
|
||||
if (groups&GUI_SETTINGS_BEHAVIOR) {
|
||||
conf.set("soloAction",settings.soloAction);
|
||||
conf.set("ctrlWheelModifier",settings.ctrlWheelModifier);
|
||||
conf.set("pullDeleteBehavior",settings.pullDeleteBehavior);
|
||||
conf.set("wrapHorizontal",settings.wrapHorizontal);
|
||||
conf.set("wrapVertical",settings.wrapVertical);
|
||||
|
|
@ -5588,6 +5636,7 @@ void FurnaceGUI::writeConfig(DivConfig& conf, FurnaceGUISettingGroups groups) {
|
|||
conf.set("opnbCore",settings.opnbCore);
|
||||
conf.set("opl2Core",settings.opl2Core);
|
||||
conf.set("opl3Core",settings.opl3Core);
|
||||
conf.set("opl4Core",settings.opl4Core);
|
||||
conf.set("esfmCore",settings.esfmCore);
|
||||
conf.set("opllCore",settings.opllCore);
|
||||
conf.set("ayCore",settings.ayCore);
|
||||
|
|
@ -5616,6 +5665,7 @@ void FurnaceGUI::writeConfig(DivConfig& conf, FurnaceGUISettingGroups groups) {
|
|||
conf.set("opnbCoreRender",settings.opnbCoreRender);
|
||||
conf.set("opl2CoreRender",settings.opl2CoreRender);
|
||||
conf.set("opl3CoreRender",settings.opl3CoreRender);
|
||||
conf.set("opl4CoreRender",settings.opl4CoreRender);
|
||||
conf.set("esfmCoreRender",settings.esfmCoreRender);
|
||||
conf.set("opllCoreRender",settings.opllCoreRender);
|
||||
conf.set("ayCoreRender",settings.ayCoreRender);
|
||||
|
|
@ -5679,6 +5729,7 @@ void FurnaceGUI::commitSettings() {
|
|||
settings.opnbCore!=e->getConfInt("opnbCore",1) ||
|
||||
settings.opl2Core!=e->getConfInt("opl2Core",0) ||
|
||||
settings.opl3Core!=e->getConfInt("opl3Core",0) ||
|
||||
settings.opl4Core!=e->getConfInt("opl4Core",0) ||
|
||||
settings.esfmCore!=e->getConfInt("esfmCore",0) ||
|
||||
settings.opllCore!=e->getConfInt("opllCore",0) ||
|
||||
settings.ayCore!=e->getConfInt("ayCore",0) ||
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ void FurnaceGUI::drawSubSongs(bool asChild) {
|
|||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
if (ImGui::Selectable(id,i==e->getCurrentSubSong())) {
|
||||
makeCursorUndo();
|
||||
e->changeSongP(i);
|
||||
updateScroll(0);
|
||||
oldRow=0;
|
||||
|
|
@ -72,6 +73,7 @@ void FurnaceGUI::drawSubSongs(bool asChild) {
|
|||
if (!e->addSubSong()) {
|
||||
showError(_("too many subsongs!"));
|
||||
} else {
|
||||
makeCursorUndo();
|
||||
e->changeSongP(e->song.subsong.size()-1);
|
||||
updateScroll(0);
|
||||
oldRow=0;
|
||||
|
|
@ -92,6 +94,7 @@ void FurnaceGUI::drawSubSongs(bool asChild) {
|
|||
if (!e->duplicateSubSong(e->getCurrentSubSong())) {
|
||||
showError(_("too many subsongs!"));
|
||||
} else {
|
||||
makeCursorUndo();
|
||||
e->changeSongP(e->song.subsong.size()-1);
|
||||
updateScroll(0);
|
||||
oldRow=0;
|
||||
|
|
|
|||
|
|
@ -1970,6 +1970,7 @@ bool FurnaceGUI::drawSysConf(int chan, int sysPos, DivSystem type, DivConfig& fl
|
|||
echoFilter[7]=flags.getInt("echoFilter7",0);
|
||||
|
||||
bool interpolationOff=flags.getBool("interpolationOff",false);
|
||||
bool antiClick=flags.getBool("antiClick",true);
|
||||
|
||||
ImGui::Text(_("Volume scale:"));
|
||||
if (CWSliderInt(_("Left##VolScaleL"),&vsL,0,127)) {
|
||||
|
|
@ -2090,6 +2091,10 @@ bool FurnaceGUI::drawSysConf(int chan, int sysPos, DivSystem type, DivConfig& fl
|
|||
altered=true;
|
||||
}
|
||||
|
||||
if (ImGui::Checkbox(_("Anti-click"),&antiClick)) {
|
||||
altered=true;
|
||||
}
|
||||
|
||||
if (altered) {
|
||||
e->lockSave([&]() {
|
||||
flags.set("volScaleL",127-vsL);
|
||||
|
|
@ -2109,6 +2114,7 @@ bool FurnaceGUI::drawSysConf(int chan, int sysPos, DivSystem type, DivConfig& fl
|
|||
flags.set("echoFilter7",echoFilter[7]);
|
||||
flags.set("echoMask",echoMask);
|
||||
flags.set("interpolationOff",interpolationOff);
|
||||
flags.set("antiClick",antiClick);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -2324,6 +2330,29 @@ bool FurnaceGUI::drawSysConf(int chan, int sysPos, DivSystem type, DivConfig& fl
|
|||
}
|
||||
break;
|
||||
}
|
||||
case DIV_SYSTEM_SUPERVISION: {
|
||||
bool swapDuty=flags.getInt("swapDuty",true);
|
||||
|
||||
if (ImGui::Checkbox(_("Swap noise duty cycles"),&swapDuty)) {
|
||||
altered=true;
|
||||
}
|
||||
|
||||
bool sqStereo=flags.getInt("sqStereo",false);
|
||||
|
||||
if (ImGui::Checkbox(_("Stereo pulse waves"),&sqStereo)) {
|
||||
altered=true;
|
||||
}
|
||||
|
||||
if (altered) {
|
||||
e->lockSave([&]() {
|
||||
flags.set("swapDuty",(int)swapDuty);
|
||||
});
|
||||
e->lockSave([&]() {
|
||||
flags.set("sqStereo",(int)sqStereo);
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DIV_SYSTEM_SM8521:/* {
|
||||
bool noAntiClick=flags.getBool("noAntiClick",false);
|
||||
|
||||
|
|
@ -2514,6 +2543,67 @@ bool FurnaceGUI::drawSysConf(int chan, int sysPos, DivSystem type, DivConfig& fl
|
|||
}
|
||||
break;
|
||||
}
|
||||
case DIV_SYSTEM_OPL4:
|
||||
case DIV_SYSTEM_OPL4_DRUMS: {
|
||||
int clockSel=flags.getInt("clockSel",0);
|
||||
int ramSize=flags.getInt("ramSize",0);
|
||||
|
||||
ImGui::Text(_("Clock rate:"));
|
||||
ImGui::Indent();
|
||||
if (ImGui::RadioButton(_("33.8688MHz"),clockSel==0)) {
|
||||
clockSel=0;
|
||||
altered=true;
|
||||
}
|
||||
if (ImGui::RadioButton(_("28.64MHz (NTSC)"),clockSel==1)) {
|
||||
clockSel=1;
|
||||
altered=true;
|
||||
}
|
||||
if (ImGui::RadioButton(_("28.38MHz (PAL)"),clockSel==2)) {
|
||||
clockSel=2;
|
||||
altered=true;
|
||||
}
|
||||
ImGui::Unindent();
|
||||
|
||||
ImGui::Text(_("RAM size:"));
|
||||
ImGui::Indent();
|
||||
if (ImGui::RadioButton(_("4MB"),ramSize==0)) {
|
||||
ramSize=0;
|
||||
altered=true;
|
||||
}
|
||||
if (ImGui::RadioButton(_("2MB"),ramSize==1)) {
|
||||
ramSize=1;
|
||||
altered=true;
|
||||
}
|
||||
if (ImGui::RadioButton(_("1MB"),ramSize==2)) {
|
||||
ramSize=2;
|
||||
altered=true;
|
||||
}
|
||||
if (ImGui::RadioButton(_("640KB"),ramSize==3)) {
|
||||
ramSize=3;
|
||||
altered=true;
|
||||
}
|
||||
if (ImGui::RadioButton(_("512KB"),ramSize==4)) {
|
||||
ramSize=4;
|
||||
altered=true;
|
||||
}
|
||||
if (ImGui::RadioButton(_("256KB"),ramSize==5)) {
|
||||
ramSize=5;
|
||||
altered=true;
|
||||
}
|
||||
if (ImGui::RadioButton(_("128KB"),ramSize==6)) {
|
||||
ramSize=6;
|
||||
altered=true;
|
||||
}
|
||||
ImGui::Unindent();
|
||||
|
||||
if (altered) {
|
||||
e->lockSave([&]() {
|
||||
flags.set("clockSel",clockSel);
|
||||
flags.set("ramSize",ramSize);
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DIV_SYSTEM_SWAN:
|
||||
case DIV_SYSTEM_BUBSYS_WSG:
|
||||
case DIV_SYSTEM_PET:
|
||||
|
|
@ -2522,6 +2612,7 @@ bool FurnaceGUI::drawSysConf(int chan, int sysPos, DivSystem type, DivConfig& fl
|
|||
case DIV_SYSTEM_C219:
|
||||
case DIV_SYSTEM_BIFURCATOR:
|
||||
case DIV_SYSTEM_POWERNOISE:
|
||||
case DIV_SYSTEM_UPD1771C:
|
||||
break;
|
||||
case DIV_SYSTEM_YMU759:
|
||||
case DIV_SYSTEM_ESFM:
|
||||
|
|
|
|||
|
|
@ -279,6 +279,12 @@ const char* FurnaceGUI::getSystemPartNumber(DivSystem sys, DivConfig& flags) {
|
|||
break;
|
||||
case DIV_SYSTEM_ESFM:
|
||||
return "ES1xxx";
|
||||
case DIV_SYSTEM_SUPERVISION:
|
||||
return "Watara Supervision";
|
||||
break;
|
||||
case DIV_SYSTEM_UPD1771C:
|
||||
return "μPD1771C";
|
||||
break;
|
||||
default:
|
||||
return FurnaceGUI::getSystemName(sys);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -475,7 +475,8 @@ void FurnaceGUI::drawUserPresets() {
|
|||
ImGui::SetTooltip(_(
|
||||
"insert additional settings in `option=value` format.\n"
|
||||
"available options:\n"
|
||||
"- tickRate"
|
||||
"- tickRate \n"
|
||||
"- chanMask \n"
|
||||
));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -948,6 +948,7 @@ void FurnaceGUI::drawWaveEdit() {
|
|||
wave->len=waveGenScaleX;
|
||||
MARK_MODIFIED;
|
||||
});
|
||||
e->notifyWaveChange(curWave);
|
||||
}
|
||||
|
||||
ImGui::TableNextRow();
|
||||
|
|
@ -966,6 +967,7 @@ void FurnaceGUI::drawWaveEdit() {
|
|||
wave->max=waveGenScaleY-1;
|
||||
MARK_MODIFIED;
|
||||
});
|
||||
e->notifyWaveChange(curWave);
|
||||
}
|
||||
|
||||
ImGui::TableNextRow();
|
||||
|
|
@ -988,6 +990,7 @@ void FurnaceGUI::drawWaveEdit() {
|
|||
}
|
||||
MARK_MODIFIED;
|
||||
});
|
||||
e->notifyWaveChange(curWave);
|
||||
}
|
||||
|
||||
ImGui::TableNextRow();
|
||||
|
|
@ -1005,6 +1008,7 @@ void FurnaceGUI::drawWaveEdit() {
|
|||
}
|
||||
MARK_MODIFIED;
|
||||
});
|
||||
e->notifyWaveChange(curWave);
|
||||
}
|
||||
|
||||
ImGui::TableNextRow();
|
||||
|
|
@ -1031,6 +1035,7 @@ void FurnaceGUI::drawWaveEdit() {
|
|||
}
|
||||
MARK_MODIFIED;
|
||||
});
|
||||
e->notifyWaveChange(curWave);
|
||||
}
|
||||
|
||||
ImGui::TableNextRow();
|
||||
|
|
@ -1050,6 +1055,7 @@ void FurnaceGUI::drawWaveEdit() {
|
|||
}
|
||||
MARK_MODIFIED;
|
||||
});
|
||||
e->notifyWaveChange(curWave);
|
||||
}
|
||||
|
||||
ImGui::EndTable();
|
||||
|
|
@ -1093,6 +1099,7 @@ void FurnaceGUI::drawWaveEdit() {
|
|||
}
|
||||
MARK_MODIFIED;
|
||||
});
|
||||
e->notifyWaveChange(curWave);
|
||||
}
|
||||
if (ImGui::Button(_("Invert"),buttonSizeHalf)) {
|
||||
e->lockEngine([this,wave]() {
|
||||
|
|
@ -1101,6 +1108,7 @@ void FurnaceGUI::drawWaveEdit() {
|
|||
}
|
||||
MARK_MODIFIED;
|
||||
});
|
||||
e->notifyWaveChange(curWave);
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(_("Reverse"),buttonSizeHalf)) {
|
||||
|
|
@ -1113,6 +1121,7 @@ void FurnaceGUI::drawWaveEdit() {
|
|||
}
|
||||
MARK_MODIFIED;
|
||||
});
|
||||
e->notifyWaveChange(curWave);
|
||||
}
|
||||
|
||||
if (ImGui::Button(_("Half"),buttonSizeHalf)) {
|
||||
|
|
@ -1122,6 +1131,7 @@ void FurnaceGUI::drawWaveEdit() {
|
|||
for (int i=0; i<wave->len; i++) {
|
||||
wave->data[i]=origData[i>>1];
|
||||
}
|
||||
e->notifyWaveChange(curWave);
|
||||
MARK_MODIFIED;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
|
|
@ -1132,6 +1142,7 @@ void FurnaceGUI::drawWaveEdit() {
|
|||
for (int i=0; i<wave->len; i++) {
|
||||
wave->data[i]=origData[(i*2)%wave->len];
|
||||
}
|
||||
e->notifyWaveChange(curWave);
|
||||
MARK_MODIFIED;
|
||||
}
|
||||
|
||||
|
|
@ -1146,6 +1157,7 @@ void FurnaceGUI::drawWaveEdit() {
|
|||
}
|
||||
MARK_MODIFIED;
|
||||
});
|
||||
e->notifyWaveChange(curWave);
|
||||
}
|
||||
if (ImGui::Button(_("Randomize"),buttonSize)) {
|
||||
if (wave->max>0) e->lockEngine([this,wave]() {
|
||||
|
|
@ -1154,6 +1166,7 @@ void FurnaceGUI::drawWaveEdit() {
|
|||
}
|
||||
MARK_MODIFIED;
|
||||
});
|
||||
e->notifyWaveChange(curWave);
|
||||
}
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue