parent
eafbf24290
commit
7ec4f7cb9e
|
@ -472,7 +472,9 @@ class DivEngine {
|
||||||
// specify system to build ROM for.
|
// specify system to build ROM for.
|
||||||
SafeWriter* buildROM(int sys);
|
SafeWriter* buildROM(int sys);
|
||||||
// dump to VGM.
|
// dump to VGM.
|
||||||
SafeWriter* saveVGM(bool* sysToExport=NULL, bool loop=true, int version=0x171);
|
SafeWriter* saveVGM(bool* sysToExport=NULL, bool loop=true, int version=0x171, bool patternHints=false);
|
||||||
|
// dump command stream.
|
||||||
|
SafeWriter* saveCommand(bool binary=false);
|
||||||
// export to an audio file
|
// export to an audio file
|
||||||
bool saveAudio(const char* path, int loops, DivAudioExportModes mode, double fadeOutTime=0.0);
|
bool saveAudio(const char* path, int loops, DivAudioExportModes mode, double fadeOutTime=0.0);
|
||||||
// wait for audio export to finish
|
// wait for audio export to finish
|
||||||
|
|
|
@ -802,7 +802,7 @@ void DivEngine::performVGMWrite(SafeWriter* w, DivSystem sys, DivRegWrite& write
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version) {
|
SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool patternHints) {
|
||||||
if (version<0x150) {
|
if (version<0x150) {
|
||||||
lastError="VGM version is too low";
|
lastError="VGM version is too low";
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1795,6 +1795,12 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version) {
|
||||||
playSub(false);
|
playSub(false);
|
||||||
size_t tickCount=0;
|
size_t tickCount=0;
|
||||||
bool writeLoop=false;
|
bool writeLoop=false;
|
||||||
|
int ord=-1;
|
||||||
|
int exportChans=0;
|
||||||
|
for (int i=0; i<chans; i++) {
|
||||||
|
if (!willExport[dispatchOfChan[i]]) continue;
|
||||||
|
exportChans++;
|
||||||
|
}
|
||||||
while (!done) {
|
while (!done) {
|
||||||
if (loopPos==-1) {
|
if (loopPos==-1) {
|
||||||
if (loopOrder==curOrder && loopRow==curRow && ticks==1) {
|
if (loopOrder==curOrder && loopRow==curRow && ticks==1) {
|
||||||
|
@ -1820,6 +1826,26 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version) {
|
||||||
writeLoop=false;
|
writeLoop=false;
|
||||||
loopPos=-1;
|
loopPos=-1;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// check for pattern change
|
||||||
|
if (prevOrder!=ord) {
|
||||||
|
logI("registering order change %d on %d",prevOrder, prevRow);
|
||||||
|
ord=prevOrder;
|
||||||
|
|
||||||
|
if (patternHints) {
|
||||||
|
w->writeC(0x67);
|
||||||
|
w->writeC(0x66);
|
||||||
|
w->writeC(0xfe);
|
||||||
|
w->writeI(3+exportChans);
|
||||||
|
w->writeC(0x01);
|
||||||
|
w->writeC(prevOrder);
|
||||||
|
w->writeC(prevRow);
|
||||||
|
for (int i=0; i<chans; i++) {
|
||||||
|
if (!willExport[dispatchOfChan[i]]) continue;
|
||||||
|
w->writeC(curSubSong->orders.ord[i][prevOrder]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// get register dumps
|
// get register dumps
|
||||||
for (int i=0; i<song.systemLen; i++) {
|
for (int i=0; i<song.systemLen; i++) {
|
||||||
|
|
|
@ -2901,6 +2901,22 @@ bool FurnaceGUI::loop() {
|
||||||
ImGui::EndCombo();
|
ImGui::EndCombo();
|
||||||
}
|
}
|
||||||
ImGui::Checkbox("loop",&vgmExportLoop);
|
ImGui::Checkbox("loop",&vgmExportLoop);
|
||||||
|
ImGui::Checkbox("add pattern change hints",&vgmExportPatternHints);
|
||||||
|
if (ImGui::IsItemHovered()) {
|
||||||
|
ImGui::SetTooltip(
|
||||||
|
"inserts data blocks on pattern changes.\n"
|
||||||
|
"useful if you are writing a playback routine.\n\n"
|
||||||
|
|
||||||
|
"the format of a pattern change data block is:\n"
|
||||||
|
"67 66 FE ll ll ll ll 01 oo rr pp pp pp ...\n"
|
||||||
|
"- ll: length, a 32-bit little-endian number\n"
|
||||||
|
"- oo: order\n"
|
||||||
|
"- rr: initial row (a 0Dxx effect is able to select a different row)\n"
|
||||||
|
"- pp: pattern index (one per channel)\n\n"
|
||||||
|
|
||||||
|
"pattern indexes are ordered as they appear in the song."
|
||||||
|
);
|
||||||
|
}
|
||||||
ImGui::Text("systems to export:");
|
ImGui::Text("systems to export:");
|
||||||
bool hasOneAtLeast=false;
|
bool hasOneAtLeast=false;
|
||||||
for (int i=0; i<e->song.systemLen; i++) {
|
for (int i=0; i<e->song.systemLen; i++) {
|
||||||
|
@ -3468,7 +3484,7 @@ bool FurnaceGUI::loop() {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GUI_FILE_EXPORT_VGM: {
|
case GUI_FILE_EXPORT_VGM: {
|
||||||
SafeWriter* w=e->saveVGM(willExport,vgmExportLoop,vgmExportVersion);
|
SafeWriter* w=e->saveVGM(willExport,vgmExportLoop,vgmExportVersion,vgmExportPatternHints);
|
||||||
if (w!=NULL) {
|
if (w!=NULL) {
|
||||||
FILE* f=ps_fopen(copyOfName.c_str(),"wb");
|
FILE* f=ps_fopen(copyOfName.c_str(),"wb");
|
||||||
if (f!=NULL) {
|
if (f!=NULL) {
|
||||||
|
@ -4431,6 +4447,7 @@ FurnaceGUI::FurnaceGUI():
|
||||||
displayError(false),
|
displayError(false),
|
||||||
displayExporting(false),
|
displayExporting(false),
|
||||||
vgmExportLoop(true),
|
vgmExportLoop(true),
|
||||||
|
vgmExportPatternHints(false),
|
||||||
wantCaptureKeyboard(false),
|
wantCaptureKeyboard(false),
|
||||||
oldWantCaptureKeyboard(false),
|
oldWantCaptureKeyboard(false),
|
||||||
displayMacroMenu(false),
|
displayMacroMenu(false),
|
||||||
|
|
|
@ -952,7 +952,7 @@ class FurnaceGUI {
|
||||||
String mmlString[32];
|
String mmlString[32];
|
||||||
String mmlStringW;
|
String mmlStringW;
|
||||||
|
|
||||||
bool quit, warnQuit, willCommit, edit, modified, displayError, displayExporting, vgmExportLoop, wantCaptureKeyboard, oldWantCaptureKeyboard, displayMacroMenu;
|
bool quit, warnQuit, willCommit, edit, modified, displayError, displayExporting, vgmExportLoop, vgmExportPatternHints, wantCaptureKeyboard, oldWantCaptureKeyboard, displayMacroMenu;
|
||||||
bool displayNew, fullScreen, preserveChanPos, wantScrollList, noteInputPoly;
|
bool displayNew, fullScreen, preserveChanPos, wantScrollList, noteInputPoly;
|
||||||
bool displayPendingIns, pendingInsSingle;
|
bool displayPendingIns, pendingInsSingle;
|
||||||
bool willExport[32];
|
bool willExport[32];
|
||||||
|
|
Loading…
Reference in New Issue