VGM export: add option to insert pattern change hi

nts
This commit is contained in:
tildearrow 2022-08-03 18:44:45 -05:00
parent eafbf24290
commit 7ec4f7cb9e
4 changed files with 49 additions and 4 deletions

View File

@ -472,7 +472,9 @@ class DivEngine {
// specify system to build ROM for.
SafeWriter* buildROM(int sys);
// 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
bool saveAudio(const char* path, int loops, DivAudioExportModes mode, double fadeOutTime=0.0);
// wait for audio export to finish

View File

@ -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) {
lastError="VGM version is too low";
return NULL;
@ -1795,6 +1795,12 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version) {
playSub(false);
size_t tickCount=0;
bool writeLoop=false;
int ord=-1;
int exportChans=0;
for (int i=0; i<chans; i++) {
if (!willExport[dispatchOfChan[i]]) continue;
exportChans++;
}
while (!done) {
if (loopPos==-1) {
if (loopOrder==curOrder && loopRow==curRow && ticks==1) {
@ -1820,6 +1826,26 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version) {
writeLoop=false;
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
for (int i=0; i<song.systemLen; i++) {

View File

@ -2901,6 +2901,22 @@ bool FurnaceGUI::loop() {
ImGui::EndCombo();
}
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:");
bool hasOneAtLeast=false;
for (int i=0; i<e->song.systemLen; i++) {
@ -3468,7 +3484,7 @@ bool FurnaceGUI::loop() {
}
break;
case GUI_FILE_EXPORT_VGM: {
SafeWriter* w=e->saveVGM(willExport,vgmExportLoop,vgmExportVersion);
SafeWriter* w=e->saveVGM(willExport,vgmExportLoop,vgmExportVersion,vgmExportPatternHints);
if (w!=NULL) {
FILE* f=ps_fopen(copyOfName.c_str(),"wb");
if (f!=NULL) {
@ -4431,6 +4447,7 @@ FurnaceGUI::FurnaceGUI():
displayError(false),
displayExporting(false),
vgmExportLoop(true),
vgmExportPatternHints(false),
wantCaptureKeyboard(false),
oldWantCaptureKeyboard(false),
displayMacroMenu(false),

View File

@ -952,7 +952,7 @@ class FurnaceGUI {
String mmlString[32];
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 displayPendingIns, pendingInsSingle;
bool willExport[32];