support .dmf with 6-bit wavetables

This commit is contained in:
tildearrow 2022-04-07 20:13:11 -05:00
parent 500ce8086d
commit 5d52ef7f00
3 changed files with 27 additions and 7 deletions

View File

@ -69,7 +69,7 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
} }
ds.version=(unsigned char)reader.readC(); ds.version=(unsigned char)reader.readC();
logI("module version %d (0x%.2x)\n",ds.version,ds.version); logI("module version %d (0x%.2x)\n",ds.version,ds.version);
if (ds.version>0x19) { if (ds.version>0x1a) {
logE("this version is not supported by Furnace yet!\n"); logE("this version is not supported by Furnace yet!\n");
lastError="this version is not supported by Furnace yet"; lastError="this version is not supported by Furnace yet";
delete[] file; delete[] file;
@ -580,6 +580,12 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
wave->data[j]=reader.readI(); wave->data[j]=reader.readI();
} }
} }
// #FDS4Bit
if (ds.system[0]==DIV_SYSTEM_NES_FDS && ds.version<0x1a) {
for (int j=0; j<wave->len; j++) {
wave->data[j]*=4;
}
}
ds.wave.push_back(wave); ds.wave.push_back(wave);
} }
} }
@ -2222,7 +2228,7 @@ SafeWriter* DivEngine::saveFur(bool notPrimary) {
SafeWriter* DivEngine::saveDMF(unsigned char version) { SafeWriter* DivEngine::saveDMF(unsigned char version) {
// fail if version is not supported // fail if version is not supported
if (version<24 || version>25) { if (version<24 || version>26) {
logE("cannot save in this version!\n"); logE("cannot save in this version!\n");
lastError="invalid version to save in! this is a bug!"; lastError="invalid version to save in! this is a bug!";
return NULL; return NULL;
@ -2273,6 +2279,12 @@ SafeWriter* DivEngine::saveDMF(unsigned char version) {
lastError="NES + VRC7 not supported in 1.0/legacy .dmf!"; lastError="NES + VRC7 not supported in 1.0/legacy .dmf!";
return NULL; return NULL;
} }
// fail if the system is FDS and version<25
if (version<25 && song.system[0]==DIV_SYSTEM_NES && song.system[1]==DIV_SYSTEM_FDS) {
logE("FDS not supported in 1.0/legacy .dmf!\n");
lastError="FDS not supported in 1.0/legacy .dmf!";
return NULL;
}
// fail if the system is Furnace-exclusive // fail if the system is Furnace-exclusive
if (!isFlat && systemToFileDMF(song.system[0])==0) { if (!isFlat && systemToFileDMF(song.system[0])==0) {
logE("cannot save Furnace-exclusive system song!\n"); logE("cannot save Furnace-exclusive system song!\n");
@ -2308,7 +2320,7 @@ SafeWriter* DivEngine::saveDMF(unsigned char version) {
sys=DIV_SYSTEM_NES_VRC7; sys=DIV_SYSTEM_NES_VRC7;
} else if (song.system[0]==DIV_SYSTEM_NES && song.system[1]==DIV_SYSTEM_FDS) { } else if (song.system[0]==DIV_SYSTEM_NES && song.system[1]==DIV_SYSTEM_FDS) {
w->writeC(systemToFileDMF(DIV_SYSTEM_NES_FDS)); w->writeC(systemToFileDMF(DIV_SYSTEM_NES_FDS));
sys=DIV_SYSTEM_NES_VRC7; sys=DIV_SYSTEM_NES_FDS;
} else { } else {
w->writeC(systemToFileDMF(song.system[0])); w->writeC(systemToFileDMF(song.system[0]));
sys=song.system[0]; sys=song.system[0];
@ -2481,8 +2493,14 @@ SafeWriter* DivEngine::saveDMF(unsigned char version) {
w->writeC(song.wave.size()); w->writeC(song.wave.size());
for (DivWavetable* i: song.wave) { for (DivWavetable* i: song.wave) {
w->writeI(i->len); w->writeI(i->len);
if (sys==DIV_SYSTEM_NES_FDS && version<26) {
for (int j=0; j<i->len; j++) {
w->writeI(i->data[j]>>2);
}
} else {
w->write(i->data,4*i->len); w->write(i->data,4*i->len);
} }
}
for (int i=0; i<getChannelCount(sys); i++) { for (int i=0; i<getChannelCount(sys); i++) {
w->writeC(song.pat[i].effectRows); w->writeC(song.pat[i].effectRows);

View File

@ -102,6 +102,8 @@ struct DivSong {
// version number used for saving the song. // version number used for saving the song.
// Furnace will save using the latest possible version, // Furnace will save using the latest possible version,
// known version numbers: // known version numbers:
// - 26: v1.1.3
// - changes height of FDS wave to 6-bit (it was 4-bit before)
// - 25: v1.1 // - 25: v1.1
// - adds pattern names (in a rather odd way) // - adds pattern names (in a rather odd way)
// - introduces SMS+OPLL system // - introduces SMS+OPLL system

View File

@ -1300,8 +1300,8 @@ void FurnaceGUI::openFileDialog(FurnaceGUIFileDialogs type) {
hasOpened=fileDialog->openSave( hasOpened=fileDialog->openSave(
"Save File", "Save File",
{"Furnace song", "*.fur", {"Furnace song", "*.fur",
"DefleMask 1.1 module", "*.dmf"}, "DefleMask 1.1.3 module", "*.dmf"},
"Furnace song{.fur},DefleMask 1.1 module{.dmf}", "Furnace song{.fur},DefleMask 1.1.3 module{.dmf}",
workingDirSong, workingDirSong,
dpiScale dpiScale
); );
@ -2714,7 +2714,7 @@ bool FurnaceGUI::loop() {
showError(fmt::sprintf("Error while saving file! (%s)",lastError)); showError(fmt::sprintf("Error while saving file! (%s)",lastError));
} }
} else { } else {
if (save(copyOfName,25)>0) { if (save(copyOfName,26)>0) {
showError(fmt::sprintf("Error while saving file! (%s)",lastError)); showError(fmt::sprintf("Error while saving file! (%s)",lastError));
} }
} }