Merge branch 'master' of github.com:tildearrow/furnace

This commit is contained in:
tildearrow 2023-08-11 19:27:17 -05:00
commit 9b91584d13
6 changed files with 23 additions and 7 deletions

View File

@ -605,7 +605,7 @@ class DivEngine {
// - -2 to add a whole loop of trailing
SafeWriter* saveVGM(bool* sysToExport=NULL, bool loop=true, int version=0x171, bool patternHints=false, bool directStream=false, int trailingTicks=-1);
// dump to ZSM.
SafeWriter* saveZSM(unsigned int zsmrate=60, bool loop=true);
SafeWriter* saveZSM(unsigned int zsmrate=60, bool loop=true, bool optimize=true);
// dump command stream.
SafeWriter* saveCommand(bool binary=false);
// export to an audio file

View File

@ -66,6 +66,8 @@ void DivZSM::init(unsigned int rate) {
// Channel masks
ymMask=0;
psgMask=0;
// Optimize writes
optimize=true;
}
int DivZSM::getoffset() {
@ -121,9 +123,6 @@ void DivZSM::writeSync(unsigned char a, unsigned char v) {
}
void DivZSM::writePSG(unsigned char a, unsigned char v) {
// TODO: suppress writes to PSG voice that is not audible (volume=0)
// ^ Let's leave these alone, ZSMKit has a feature that can benefit
// from silent channels.
if (a>=69) {
logD("ZSM: ignoring VERA PSG write a=%02x v=%02x",a,v);
return;
@ -213,6 +212,10 @@ void DivZSM::setLoopPoint() {
}
}
void DivZSM::setOptimize(bool o) {
optimize=o;
}
SafeWriter* DivZSM::finish() {
tick(0); // flush any pending writes / ticks
flushTicks(); // flush ticks in case there were no writes pending
@ -278,6 +281,11 @@ void DivZSM::flushWrites() {
flushTicks(); // only flush ticks if there are writes pending.
for (unsigned char i=0; i<64; i++) {
if (psgState[psg_NEW][i]==psgState[psg_PREV][i]) continue;
// if optimize=true, suppress writes to PSG voices that are not audible (volume=0 or R+L=0)
// ZSMKit has a feature that can benefit from having silent channels
// updated, so this is something that can be toggled off or on for export
if (optimize && (i&3)!=2 && (psgState[psg_NEW][(i&0x3c)+2]&0x3f)==0) continue; // vol
if (optimize && (i&3)!=2 && (psgState[psg_NEW][(i&0x3c)+2]&0xc0)==0) continue; // R+L
psgState[psg_PREV][i]=psgState[psg_NEW][i];
w->writeC(i);
w->writeC(psgState[psg_NEW][i]);

View File

@ -70,6 +70,7 @@ class DivZSM {
int tickRate;
int ymMask;
int psgMask;
bool optimize;
public:
DivZSM();
~DivZSM();
@ -79,6 +80,7 @@ class DivZSM {
void writePSG(unsigned char a, unsigned char v);
void writePCM(unsigned char a, unsigned char v);
void writeSync(unsigned char a, unsigned char v);
void setOptimize(bool o);
void tick(int numticks = 1);
void setLoopPoint();
SafeWriter* finish();

View File

@ -26,7 +26,7 @@
constexpr int MASTER_CLOCK_PREC=(sizeof(void*)==8)?8:0;
constexpr int MASTER_CLOCK_MASK=(sizeof(void*)==8)?0xff:0;
SafeWriter* DivEngine::saveZSM(unsigned int zsmrate, bool loop) {
SafeWriter* DivEngine::saveZSM(unsigned int zsmrate, bool loop, bool optimize) {
int VERA=-1;
int YM=-1;
int IGNORED=0;
@ -118,6 +118,9 @@ SafeWriter* DivEngine::saveZSM(unsigned int zsmrate, bool loop) {
// by nature of overflowing the signed char value
signed char tuningoffset=(signed char)(round(3072*(log(song.tuning/440.0)/log(2))))&0xff;
zsm.writeSync(0x01,tuningoffset);
// Set optimize flag, which mainly buffers PSG writes
// whenever the channel is silent
zsm.setOptimize(optimize);
while (!done) {
if (loopPos==-1) {

View File

@ -4108,6 +4108,8 @@ bool FurnaceGUI::loop() {
}
ImGui::Checkbox("loop",&zsmExportLoop);
ImGui::SameLine();
ImGui::Checkbox("optimize size",&zsmExportOptimize);
ImGui::SameLine();
if (ImGui::Button("Begin Export")) {
openFileDialog(GUI_FILE_EXPORT_ZSM);
ImGui::CloseCurrentPopup();
@ -5071,7 +5073,7 @@ bool FurnaceGUI::loop() {
break;
}
case GUI_FILE_EXPORT_ZSM: {
SafeWriter* w=e->saveZSM(zsmExportTickRate,zsmExportLoop);
SafeWriter* w=e->saveZSM(zsmExportTickRate,zsmExportLoop,zsmExportOptimize);
if (w!=NULL) {
FILE* f=ps_fopen(copyOfName.c_str(),"wb");
if (f!=NULL) {
@ -6803,6 +6805,7 @@ FurnaceGUI::FurnaceGUI():
displayExporting(false),
vgmExportLoop(true),
zsmExportLoop(true),
zsmExportOptimize(true),
vgmExportPatternHints(false),
vgmExportDirectStream(false),
displayInsTypeList(false),

View File

@ -1324,7 +1324,7 @@ class FurnaceGUI {
std::vector<String> availRenderDrivers;
std::vector<String> availAudioDrivers;
bool quit, warnQuit, willCommit, edit, modified, displayError, displayExporting, vgmExportLoop, zsmExportLoop, vgmExportPatternHints;
bool quit, warnQuit, willCommit, edit, modified, displayError, displayExporting, vgmExportLoop, zsmExportLoop, zsmExportOptimize, vgmExportPatternHints;
bool vgmExportDirectStream, displayInsTypeList;
bool portrait, injectBackUp, mobileMenuOpen, warnColorPushed;
bool wantCaptureKeyboard, oldWantCaptureKeyboard, displayMacroMenu;