parent
d211170e86
commit
859b2cf8db
|
@ -644,10 +644,79 @@ void DivEngine::createNew(const int* description) {
|
||||||
BUSY_END;
|
BUSY_END;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DivEngine::changeSystem(int index, DivSystem which) {
|
void DivEngine::swapChannels(int src, int dest) {
|
||||||
|
logV("swapping channel %d with %d",src,dest);
|
||||||
|
if (src==dest) {
|
||||||
|
logV("not swapping channels because it's the same channel!",src,dest);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i=0; i<256; i++) {
|
||||||
|
song.orders.ord[dest][i]^=song.orders.ord[src][i];
|
||||||
|
song.orders.ord[src][i]^=song.orders.ord[dest][i];
|
||||||
|
song.orders.ord[dest][i]^=song.orders.ord[src][i];
|
||||||
|
|
||||||
|
DivPattern* prev=song.pat[src].data[i];
|
||||||
|
song.pat[src].data[i]=song.pat[dest].data[i];
|
||||||
|
song.pat[dest].data[i]=prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
song.pat[src].effectCols^=song.pat[dest].effectCols;
|
||||||
|
song.pat[dest].effectCols^=song.pat[src].effectCols;
|
||||||
|
song.pat[src].effectCols^=song.pat[dest].effectCols;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DivEngine::stompChannel(int ch) {
|
||||||
|
logV("stomping channel %d",ch);
|
||||||
|
for (int i=0; i<256; i++) {
|
||||||
|
song.orders.ord[ch][i]=0;
|
||||||
|
}
|
||||||
|
song.pat[ch].wipePatterns();
|
||||||
|
song.pat[ch].effectCols=1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DivEngine::swapChannelsP(int src, int dest) {
|
||||||
|
if (src<0 || src>=chans) return;
|
||||||
|
if (dest<0 || dest>=chans) return;
|
||||||
|
BUSY_BEGIN;
|
||||||
|
saveLock.lock();
|
||||||
|
swapChannels(src,dest);
|
||||||
|
saveLock.unlock();
|
||||||
|
BUSY_END;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DivEngine::changeSystem(int index, DivSystem which, bool preserveOrder) {
|
||||||
|
int chanCount=chans;
|
||||||
quitDispatch();
|
quitDispatch();
|
||||||
BUSY_BEGIN;
|
BUSY_BEGIN;
|
||||||
saveLock.lock();
|
saveLock.lock();
|
||||||
|
|
||||||
|
if (!preserveOrder) {
|
||||||
|
int firstChan=0;
|
||||||
|
int chanMovement=getChannelCount(which)-getChannelCount(song.system[index]);
|
||||||
|
while (dispatchOfChan[firstChan]!=index) firstChan++;
|
||||||
|
int lastChan=firstChan+getChannelCount(song.system[index]);
|
||||||
|
if (chanMovement!=0) {
|
||||||
|
if (chanMovement>0) {
|
||||||
|
// add channels
|
||||||
|
for (int i=chanCount+chanMovement-1; i>=lastChan+chanMovement; i--) {
|
||||||
|
swapChannels(i,i-chanMovement);
|
||||||
|
}
|
||||||
|
for (int i=lastChan; i<lastChan+chanMovement; i++) {
|
||||||
|
stompChannel(i);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// remove channels
|
||||||
|
for (int i=lastChan+chanMovement; i<lastChan; i++) {
|
||||||
|
stompChannel(i);
|
||||||
|
}
|
||||||
|
for (int i=lastChan+chanMovement; i<chanCount+chanMovement; i++) {
|
||||||
|
swapChannels(i,i-chanMovement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
song.system[index]=which;
|
song.system[index]=which;
|
||||||
song.systemFlags[index]=0;
|
song.systemFlags[index]=0;
|
||||||
recalcChans();
|
recalcChans();
|
||||||
|
@ -688,7 +757,7 @@ bool DivEngine::addSystem(DivSystem which) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DivEngine::removeSystem(int index) {
|
bool DivEngine::removeSystem(int index, bool preserveOrder) {
|
||||||
if (song.systemLen<=1) {
|
if (song.systemLen<=1) {
|
||||||
lastError="cannot remove the last one";
|
lastError="cannot remove the last one";
|
||||||
return false;
|
return false;
|
||||||
|
@ -697,13 +766,29 @@ bool DivEngine::removeSystem(int index) {
|
||||||
lastError="invalid index";
|
lastError="invalid index";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
int chanCount=chans;
|
||||||
quitDispatch();
|
quitDispatch();
|
||||||
BUSY_BEGIN;
|
BUSY_BEGIN;
|
||||||
saveLock.lock();
|
saveLock.lock();
|
||||||
|
|
||||||
|
if (!preserveOrder) {
|
||||||
|
int firstChan=0;
|
||||||
|
while (dispatchOfChan[firstChan]!=index) firstChan++;
|
||||||
|
for (int i=0; i<getChannelCount(song.system[index]); i++) {
|
||||||
|
stompChannel(i+firstChan);
|
||||||
|
}
|
||||||
|
for (int i=firstChan+getChannelCount(song.system[index]); i<chanCount; i++) {
|
||||||
|
swapChannels(i,i-getChannelCount(song.system[index]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
song.system[index]=DIV_SYSTEM_NULL;
|
song.system[index]=DIV_SYSTEM_NULL;
|
||||||
song.systemLen--;
|
song.systemLen--;
|
||||||
for (int i=index; i<song.systemLen; i++) {
|
for (int i=index; i<song.systemLen; i++) {
|
||||||
song.system[i]=song.system[i+1];
|
song.system[i]=song.system[i+1];
|
||||||
|
song.systemVol[i]=song.systemVol[i+1];
|
||||||
|
song.systemPan[i]=song.systemPan[i+1];
|
||||||
|
song.systemFlags[i]=song.systemFlags[i+1];
|
||||||
}
|
}
|
||||||
recalcChans();
|
recalcChans();
|
||||||
saveLock.unlock();
|
saveLock.unlock();
|
||||||
|
@ -1059,7 +1144,6 @@ void DivEngine::recalcChans() {
|
||||||
if (sysDefs[song.system[i]]!=NULL) {
|
if (sysDefs[song.system[i]]!=NULL) {
|
||||||
if (sysDefs[song.system[i]]->chanInsType[j][0]!=DIV_INS_NULL) {
|
if (sysDefs[song.system[i]]->chanInsType[j][0]!=DIV_INS_NULL) {
|
||||||
isInsTypePossible[sysDefs[song.system[i]]->chanInsType[j][0]]=true;
|
isInsTypePossible[sysDefs[song.system[i]]->chanInsType[j][0]]=true;
|
||||||
logV("Marking");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sysDefs[song.system[i]]->chanInsType[j][1]!=DIV_INS_NULL) {
|
if (sysDefs[song.system[i]]->chanInsType[j][1]!=DIV_INS_NULL) {
|
||||||
|
|
|
@ -395,6 +395,8 @@ class DivEngine {
|
||||||
void registerSystems();
|
void registerSystems();
|
||||||
|
|
||||||
void exchangeIns(int one, int two);
|
void exchangeIns(int one, int two);
|
||||||
|
void swapChannels(int src, int dest);
|
||||||
|
void stompChannel(int ch);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DivSong song;
|
DivSong song;
|
||||||
|
@ -762,14 +764,17 @@ class DivEngine {
|
||||||
// public render samples
|
// public render samples
|
||||||
void renderSamplesP();
|
void renderSamplesP();
|
||||||
|
|
||||||
|
// public swap channels
|
||||||
|
void swapChannelsP(int src, int dest);
|
||||||
|
|
||||||
// change system
|
// change system
|
||||||
void changeSystem(int index, DivSystem which);
|
void changeSystem(int index, DivSystem which, bool preserveOrder=true);
|
||||||
|
|
||||||
// add system
|
// add system
|
||||||
bool addSystem(DivSystem which);
|
bool addSystem(DivSystem which);
|
||||||
|
|
||||||
// remove system
|
// remove system
|
||||||
bool removeSystem(int index);
|
bool removeSystem(int index, bool preserveOrder=true);
|
||||||
|
|
||||||
// write to register on system
|
// write to register on system
|
||||||
void poke(int sys, unsigned int addr, unsigned short val);
|
void poke(int sys, unsigned int addr, unsigned short val);
|
||||||
|
|
|
@ -19,6 +19,8 @@
|
||||||
|
|
||||||
#include "gui.h"
|
#include "gui.h"
|
||||||
#include "misc/cpp/imgui_stdlib.h"
|
#include "misc/cpp/imgui_stdlib.h"
|
||||||
|
#include "IconsFontAwesome4.h"
|
||||||
|
#include <imgui.h>
|
||||||
|
|
||||||
void FurnaceGUI::drawChannels() {
|
void FurnaceGUI::drawChannels() {
|
||||||
if (nextWindow==GUI_WINDOW_CHANNELS) {
|
if (nextWindow==GUI_WINDOW_CHANNELS) {
|
||||||
|
@ -37,6 +39,18 @@ void FurnaceGUI::drawChannels() {
|
||||||
ImGui::TableNextRow();
|
ImGui::TableNextRow();
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
ImGui::Checkbox("##Visible",&e->song.chanShow[i]);
|
ImGui::Checkbox("##Visible",&e->song.chanShow[i]);
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::BeginDisabled(i==0);
|
||||||
|
if (ImGui::Button(ICON_FA_CHEVRON_UP)) {
|
||||||
|
e->swapChannelsP(i,i-1);
|
||||||
|
}
|
||||||
|
ImGui::EndDisabled();
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::BeginDisabled(i==(e->getTotalChannelCount()-1));
|
||||||
|
if (ImGui::Button(ICON_FA_CHEVRON_DOWN)) {
|
||||||
|
e->swapChannelsP(i,i+1);
|
||||||
|
}
|
||||||
|
ImGui::EndDisabled();
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||||
ImGui::InputTextWithHint("##ChanName",e->getChannelName(i),&e->song.chanName[i]);
|
ImGui::InputTextWithHint("##ChanName",e->getChannelName(i),&e->song.chanName[i]);
|
||||||
|
|
|
@ -1812,7 +1812,7 @@ void FurnaceGUI::processDrags(int dragX, int dragY) {
|
||||||
|
|
||||||
#define sysChangeOption(x,y) \
|
#define sysChangeOption(x,y) \
|
||||||
if (ImGui::MenuItem(getSystemName(y),NULL,e->song.system[x]==y)) { \
|
if (ImGui::MenuItem(getSystemName(y),NULL,e->song.system[x]==y)) { \
|
||||||
e->changeSystem(x,y); \
|
e->changeSystem(x,y,preserveChanPos); \
|
||||||
updateWindowTitle(); \
|
updateWindowTitle(); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2687,6 +2687,7 @@ bool FurnaceGUI::loop() {
|
||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
}
|
}
|
||||||
if (ImGui::BeginMenu("change system...")) {
|
if (ImGui::BeginMenu("change system...")) {
|
||||||
|
ImGui::Checkbox("Preserve channel positions",&preserveChanPos);
|
||||||
for (int i=0; i<e->song.systemLen; i++) {
|
for (int i=0; i<e->song.systemLen; i++) {
|
||||||
if (ImGui::BeginMenu(fmt::sprintf("%d. %s##_SYSC%d",i+1,getSystemName(e->song.system[i]),i).c_str())) {
|
if (ImGui::BeginMenu(fmt::sprintf("%d. %s##_SYSC%d",i+1,getSystemName(e->song.system[i]),i).c_str())) {
|
||||||
for (int j=0; availableSystems[j]; j++) {
|
for (int j=0; availableSystems[j]; j++) {
|
||||||
|
@ -2699,9 +2700,10 @@ bool FurnaceGUI::loop() {
|
||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
}
|
}
|
||||||
if (ImGui::BeginMenu("remove system...")) {
|
if (ImGui::BeginMenu("remove system...")) {
|
||||||
|
ImGui::Checkbox("Preserve channel positions",&preserveChanPos);
|
||||||
for (int i=0; i<e->song.systemLen; i++) {
|
for (int i=0; i<e->song.systemLen; i++) {
|
||||||
if (ImGui::MenuItem(fmt::sprintf("%d. %s##_SYSR%d",i+1,getSystemName(e->song.system[i]),i).c_str())) {
|
if (ImGui::MenuItem(fmt::sprintf("%d. %s##_SYSR%d",i+1,getSystemName(e->song.system[i]),i).c_str())) {
|
||||||
if (!e->removeSystem(i)) {
|
if (!e->removeSystem(i,preserveChanPos)) {
|
||||||
showError("cannot remove system! ("+e->getLastError()+")");
|
showError("cannot remove system! ("+e->getLastError()+")");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3782,6 +3784,7 @@ FurnaceGUI::FurnaceGUI():
|
||||||
wantCaptureKeyboard(false),
|
wantCaptureKeyboard(false),
|
||||||
displayNew(false),
|
displayNew(false),
|
||||||
fullScreen(false),
|
fullScreen(false),
|
||||||
|
preserveChanPos(false),
|
||||||
vgmExportVersion(0x171),
|
vgmExportVersion(0x171),
|
||||||
drawHalt(10),
|
drawHalt(10),
|
||||||
curFileDialog(GUI_FILE_OPEN),
|
curFileDialog(GUI_FILE_OPEN),
|
||||||
|
|
|
@ -735,7 +735,7 @@ class FurnaceGUI {
|
||||||
String mmlStringW;
|
String mmlStringW;
|
||||||
|
|
||||||
bool quit, warnQuit, willCommit, edit, modified, displayError, displayExporting, vgmExportLoop, wantCaptureKeyboard;
|
bool quit, warnQuit, willCommit, edit, modified, displayError, displayExporting, vgmExportLoop, wantCaptureKeyboard;
|
||||||
bool displayNew, fullScreen;
|
bool displayNew, fullScreen, preserveChanPos;
|
||||||
bool willExport[32];
|
bool willExport[32];
|
||||||
int vgmExportVersion;
|
int vgmExportVersion;
|
||||||
int drawHalt;
|
int drawHalt;
|
||||||
|
|
Loading…
Reference in a new issue