preliminary 1.1 .dmf loading
This commit is contained in:
parent
9eb6d1cfc1
commit
464ad5a825
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
#include "engine.h"
|
#include "engine.h"
|
||||||
#include "../ta-log.h"
|
#include "../ta-log.h"
|
||||||
|
#include "song.h"
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
#include <fmt/printf.h>
|
#include <fmt/printf.h>
|
||||||
|
|
||||||
|
@ -60,7 +61,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>0x18) {
|
if (ds.version>0x19) {
|
||||||
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;
|
||||||
|
@ -206,10 +207,17 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
||||||
addWarning("Yamaha YMU759 emulation is not currently possible!");
|
addWarning("Yamaha YMU759 emulation is not currently possible!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ds.system[0]==DIV_SYSTEM_SMS_OPLL) {
|
||||||
|
addWarning("Master System FM expansion is not emulated yet. wait for 0.6!");
|
||||||
|
}
|
||||||
|
|
||||||
logI("reading pattern matrix (%d)...\n",ds.ordersLen);
|
logI("reading pattern matrix (%d)...\n",ds.ordersLen);
|
||||||
for (int i=0; i<getChannelCount(ds.system[0]); i++) {
|
for (int i=0; i<getChannelCount(ds.system[0]); i++) {
|
||||||
for (int j=0; j<ds.ordersLen; j++) {
|
for (int j=0; j<ds.ordersLen; j++) {
|
||||||
ds.orders.ord[i][j]=reader.readC();
|
ds.orders.ord[i][j]=reader.readC();
|
||||||
|
if (ds.version>0x18) { // 1.1 pattern names
|
||||||
|
ds.pat[i].getPattern(j,true)->name=reader.readString((unsigned char)reader.readC());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,6 +257,9 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
||||||
ins->type=DIV_INS_PCE;
|
ins->type=DIV_INS_PCE;
|
||||||
ins->std.volMacroHeight=31;
|
ins->std.volMacroHeight=31;
|
||||||
}
|
}
|
||||||
|
if (ds.system[0]==DIV_SYSTEM_SMS_OPLL) {
|
||||||
|
ins->type=DIV_INS_OPLL;
|
||||||
|
}
|
||||||
|
|
||||||
if (ins->mode) { // FM
|
if (ins->mode) { // FM
|
||||||
ins->fm.alg=reader.readC();
|
ins->fm.alg=reader.readC();
|
||||||
|
@ -301,13 +312,28 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
||||||
ins->fm.op[j].vib=reader.readC();
|
ins->fm.op[j].vib=reader.readC();
|
||||||
ins->fm.op[j].ws=reader.readC();
|
ins->fm.op[j].ws=reader.readC();
|
||||||
} else {
|
} else {
|
||||||
ins->fm.op[j].dt2=reader.readC();
|
if (ds.system[0]==DIV_SYSTEM_SMS_OPLL) {
|
||||||
|
if (j==0) {
|
||||||
|
ins->fm.opllPreset=reader.readC();
|
||||||
|
} else {
|
||||||
|
reader.readC();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ins->fm.op[j].dt2=reader.readC();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (ds.version>0x03) {
|
if (ds.version>0x03) {
|
||||||
ins->fm.op[j].rs=reader.readC();
|
if (ds.system[0]==DIV_SYSTEM_SMS_OPLL) {
|
||||||
ins->fm.op[j].dt=reader.readC();
|
ins->fm.op[j].ksr=reader.readC();
|
||||||
ins->fm.op[j].d2r=reader.readC();
|
ins->fm.op[j].vib=reader.readC();
|
||||||
ins->fm.op[j].ssgEnv=reader.readC();
|
ins->fm.op[j].ksl=reader.readC();
|
||||||
|
ins->fm.op[j].ssgEnv=reader.readC();
|
||||||
|
} else {
|
||||||
|
ins->fm.op[j].rs=reader.readC();
|
||||||
|
ins->fm.op[j].dt=reader.readC();
|
||||||
|
ins->fm.op[j].d2r=reader.readC();
|
||||||
|
ins->fm.op[j].ssgEnv=reader.readC();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
logD("OP%d: AM %d AR %d DAM %d DR %d DVB %d EGT %d KSL %d MULT %d RR %d SL %d SUS %d TL %d VIB %d WS %d RS %d DT %d D2R %d SSG-EG %d\n",j,
|
logD("OP%d: AM %d AR %d DAM %d DR %d DVB %d EGT %d KSL %d MULT %d RR %d SL %d SUS %d TL %d VIB %d WS %d RS %d DT %d D2R %d SSG-EG %d\n",j,
|
||||||
|
@ -610,6 +636,13 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// handle special systems
|
||||||
|
if (ds.system[0]==DIV_SYSTEM_SMS_OPLL) {
|
||||||
|
ds.systemLen=2;
|
||||||
|
ds.system[0]=DIV_SYSTEM_SMS;
|
||||||
|
ds.system[1]=DIV_SYSTEM_OPLL;
|
||||||
|
}
|
||||||
|
|
||||||
if (active) quitDispatch();
|
if (active) quitDispatch();
|
||||||
isBusy.lock();
|
isBusy.lock();
|
||||||
song.unload();
|
song.unload();
|
||||||
|
|
|
@ -50,7 +50,7 @@ enum DivInstrumentType {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DivInstrumentFM {
|
struct DivInstrumentFM {
|
||||||
unsigned char alg, fb, fms, ams, ops;
|
unsigned char alg, fb, fms, ams, ops, opllPreset;
|
||||||
struct Operator {
|
struct Operator {
|
||||||
unsigned char am, ar, dr, mult, rr, sl, tl, dt2, rs, dt, d2r, ssgEnv;
|
unsigned char am, ar, dr, mult, rr, sl, tl, dt2, rs, dt, d2r, ssgEnv;
|
||||||
unsigned char dam, dvb, egt, ksl, sus, vib, ws, ksr; // YMU759
|
unsigned char dam, dvb, egt, ksl, sus, vib, ws, ksr; // YMU759
|
||||||
|
|
|
@ -49,6 +49,11 @@ void DivChannelData::wipePatterns() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DivPattern::copyOn(DivPattern *dest) {
|
||||||
|
dest->name=name;
|
||||||
|
memcpy(dest->data,data,sizeof(data));
|
||||||
|
}
|
||||||
|
|
||||||
SafeReader* DivPattern::compile(int len, int fxRows) {
|
SafeReader* DivPattern::compile(int len, int fxRows) {
|
||||||
SafeWriter w;
|
SafeWriter w;
|
||||||
w.init();
|
w.init();
|
||||||
|
|
|
@ -20,7 +20,9 @@
|
||||||
#include "safeReader.h"
|
#include "safeReader.h"
|
||||||
|
|
||||||
struct DivPattern {
|
struct DivPattern {
|
||||||
|
String name;
|
||||||
short data[256][32];
|
short data[256][32];
|
||||||
|
void copyOn(DivPattern* dest);
|
||||||
SafeReader* compile(int len=256, int fxRows=1);
|
SafeReader* compile(int len=256, int fxRows=1);
|
||||||
DivPattern();
|
DivPattern();
|
||||||
};
|
};
|
||||||
|
|
|
@ -37,6 +37,7 @@ enum DivSystem {
|
||||||
DIV_SYSTEM_GENESIS,
|
DIV_SYSTEM_GENESIS,
|
||||||
DIV_SYSTEM_GENESIS_EXT,
|
DIV_SYSTEM_GENESIS_EXT,
|
||||||
DIV_SYSTEM_SMS,
|
DIV_SYSTEM_SMS,
|
||||||
|
DIV_SYSTEM_SMS_OPLL,
|
||||||
DIV_SYSTEM_GB,
|
DIV_SYSTEM_GB,
|
||||||
DIV_SYSTEM_PCE,
|
DIV_SYSTEM_PCE,
|
||||||
DIV_SYSTEM_NES,
|
DIV_SYSTEM_NES,
|
||||||
|
@ -92,6 +93,9 @@ 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:
|
||||||
|
// - 25: v1.1
|
||||||
|
// - adds pattern names (in a rather odd way)
|
||||||
|
// - introduces SMS+OPLL system
|
||||||
// - 24: v0.12/0.13/1.0
|
// - 24: v0.12/0.13/1.0
|
||||||
// - current format version
|
// - current format version
|
||||||
// - changes pattern length from char to int, probably to allow for size 256
|
// - changes pattern length from char to int, probably to allow for size 256
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "engine.h"
|
#include "engine.h"
|
||||||
|
#include "song.h"
|
||||||
|
|
||||||
DivSystem DivEngine::systemFromFile(unsigned char val) {
|
DivSystem DivEngine::systemFromFile(unsigned char val) {
|
||||||
switch (val) {
|
switch (val) {
|
||||||
|
@ -41,6 +42,8 @@ DivSystem DivEngine::systemFromFile(unsigned char val) {
|
||||||
return DIV_SYSTEM_YM2610;
|
return DIV_SYSTEM_YM2610;
|
||||||
case 0x42:
|
case 0x42:
|
||||||
return DIV_SYSTEM_GENESIS_EXT;
|
return DIV_SYSTEM_GENESIS_EXT;
|
||||||
|
case 0x43:
|
||||||
|
return DIV_SYSTEM_SMS_OPLL;
|
||||||
case 0x47:
|
case 0x47:
|
||||||
return DIV_SYSTEM_C64_6581;
|
return DIV_SYSTEM_C64_6581;
|
||||||
case 0x49:
|
case 0x49:
|
||||||
|
@ -152,6 +155,8 @@ unsigned char DivEngine::systemToFile(DivSystem val) {
|
||||||
return 0x09;
|
return 0x09;
|
||||||
case DIV_SYSTEM_GENESIS_EXT:
|
case DIV_SYSTEM_GENESIS_EXT:
|
||||||
return 0x42;
|
return 0x42;
|
||||||
|
case DIV_SYSTEM_SMS_OPLL:
|
||||||
|
return 0x43;
|
||||||
case DIV_SYSTEM_C64_6581:
|
case DIV_SYSTEM_C64_6581:
|
||||||
return 0x47;
|
return 0x47;
|
||||||
case DIV_SYSTEM_YM2610_EXT:
|
case DIV_SYSTEM_YM2610_EXT:
|
||||||
|
@ -265,6 +270,7 @@ int DivEngine::getChannelCount(DivSystem sys) {
|
||||||
case DIV_SYSTEM_ARCADE:
|
case DIV_SYSTEM_ARCADE:
|
||||||
case DIV_SYSTEM_GENESIS_EXT:
|
case DIV_SYSTEM_GENESIS_EXT:
|
||||||
case DIV_SYSTEM_YM2610:
|
case DIV_SYSTEM_YM2610:
|
||||||
|
case DIV_SYSTEM_SMS_OPLL:
|
||||||
return 13;
|
return 13;
|
||||||
case DIV_SYSTEM_YM2610_EXT:
|
case DIV_SYSTEM_YM2610_EXT:
|
||||||
return 16;
|
return 16;
|
||||||
|
@ -367,6 +373,8 @@ const char* DivEngine::getSystemName(DivSystem sys) {
|
||||||
return "Sega Genesis/Mega Drive";
|
return "Sega Genesis/Mega Drive";
|
||||||
case DIV_SYSTEM_SMS:
|
case DIV_SYSTEM_SMS:
|
||||||
return "Sega Master System";
|
return "Sega Master System";
|
||||||
|
case DIV_SYSTEM_SMS_OPLL:
|
||||||
|
return "Sega Master System + FM Expansion";
|
||||||
case DIV_SYSTEM_GB:
|
case DIV_SYSTEM_GB:
|
||||||
return "Game Boy";
|
return "Game Boy";
|
||||||
case DIV_SYSTEM_PCE:
|
case DIV_SYSTEM_PCE:
|
||||||
|
@ -480,6 +488,8 @@ const char* DivEngine::getSystemChips(DivSystem sys) {
|
||||||
return "Yamaha YM2612 + TI SN76489";
|
return "Yamaha YM2612 + TI SN76489";
|
||||||
case DIV_SYSTEM_SMS:
|
case DIV_SYSTEM_SMS:
|
||||||
return "TI SN76489";
|
return "TI SN76489";
|
||||||
|
case DIV_SYSTEM_SMS_OPLL:
|
||||||
|
return "TI SN76489 + Yamaha YM2413";
|
||||||
case DIV_SYSTEM_GB:
|
case DIV_SYSTEM_GB:
|
||||||
return "Game Boy";
|
return "Game Boy";
|
||||||
case DIV_SYSTEM_PCE:
|
case DIV_SYSTEM_PCE:
|
||||||
|
@ -592,6 +602,7 @@ const char* DivEngine::getSystemNameJ(DivSystem sys) {
|
||||||
case DIV_SYSTEM_GENESIS:
|
case DIV_SYSTEM_GENESIS:
|
||||||
return "セガメガドライブ";
|
return "セガメガドライブ";
|
||||||
case DIV_SYSTEM_SMS:
|
case DIV_SYSTEM_SMS:
|
||||||
|
case DIV_SYSTEM_SMS_OPLL:
|
||||||
return "セガマスターシステム";
|
return "セガマスターシステム";
|
||||||
case DIV_SYSTEM_GB:
|
case DIV_SYSTEM_GB:
|
||||||
return "ゲームボーイ";
|
return "ゲームボーイ";
|
||||||
|
@ -835,6 +846,9 @@ const char* DivEngine::getChannelName(int chan) {
|
||||||
case DIV_SYSTEM_SMS:
|
case DIV_SYSTEM_SMS:
|
||||||
return chanNames[3][dispatchChanOfChan[chan]];
|
return chanNames[3][dispatchChanOfChan[chan]];
|
||||||
break;
|
break;
|
||||||
|
case DIV_SYSTEM_SMS_OPLL: // this is flattened to SMS + OPLL.
|
||||||
|
return "??";
|
||||||
|
break;
|
||||||
case DIV_SYSTEM_GB:
|
case DIV_SYSTEM_GB:
|
||||||
return chanNames[4][dispatchChanOfChan[chan]];
|
return chanNames[4][dispatchChanOfChan[chan]];
|
||||||
break;
|
break;
|
||||||
|
@ -962,6 +976,9 @@ const char* DivEngine::getChannelShortName(int chan) {
|
||||||
case DIV_SYSTEM_SMS:
|
case DIV_SYSTEM_SMS:
|
||||||
return chanShortNames[3][dispatchChanOfChan[chan]];
|
return chanShortNames[3][dispatchChanOfChan[chan]];
|
||||||
break;
|
break;
|
||||||
|
case DIV_SYSTEM_SMS_OPLL: // this is flattened to SMS + OPLL.
|
||||||
|
return "??";
|
||||||
|
break;
|
||||||
case DIV_SYSTEM_GB:
|
case DIV_SYSTEM_GB:
|
||||||
return chanShortNames[4][dispatchChanOfChan[chan]];
|
return chanShortNames[4][dispatchChanOfChan[chan]];
|
||||||
break;
|
break;
|
||||||
|
@ -1087,6 +1104,9 @@ int DivEngine::getChannelType(int chan) {
|
||||||
case DIV_SYSTEM_SMS:
|
case DIV_SYSTEM_SMS:
|
||||||
return chanTypes[3][dispatchChanOfChan[chan]];
|
return chanTypes[3][dispatchChanOfChan[chan]];
|
||||||
break;
|
break;
|
||||||
|
case DIV_SYSTEM_SMS_OPLL: // this is flattened to SMS + OPLL.
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
case DIV_SYSTEM_GB:
|
case DIV_SYSTEM_GB:
|
||||||
return chanTypes[4][dispatchChanOfChan[chan]];
|
return chanTypes[4][dispatchChanOfChan[chan]];
|
||||||
break;
|
break;
|
||||||
|
@ -1212,6 +1232,9 @@ DivInstrumentType DivEngine::getPreferInsType(int chan) {
|
||||||
case DIV_SYSTEM_SMS:
|
case DIV_SYSTEM_SMS:
|
||||||
return chanPrefType[3][dispatchChanOfChan[chan]];
|
return chanPrefType[3][dispatchChanOfChan[chan]];
|
||||||
break;
|
break;
|
||||||
|
case DIV_SYSTEM_SMS_OPLL: // this is flattened to SMS + OPLL.
|
||||||
|
return DIV_INS_OPLL;
|
||||||
|
break;
|
||||||
case DIV_SYSTEM_GB:
|
case DIV_SYSTEM_GB:
|
||||||
return chanPrefType[4][dispatchChanOfChan[chan]];
|
return chanPrefType[4][dispatchChanOfChan[chan]];
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -2275,7 +2275,7 @@ void FurnaceGUI::prepareUndo(ActionType action) {
|
||||||
case GUI_UNDO_PATTERN_CUT:
|
case GUI_UNDO_PATTERN_CUT:
|
||||||
case GUI_UNDO_PATTERN_PASTE:
|
case GUI_UNDO_PATTERN_PASTE:
|
||||||
for (int i=0; i<e->getTotalChannelCount(); i++) {
|
for (int i=0; i<e->getTotalChannelCount(); i++) {
|
||||||
memcpy(oldPat[i],e->song.pat[i].getPattern(e->song.orders.ord[i][order],false),sizeof(DivPattern));
|
e->song.pat[i].getPattern(e->song.orders.ord[i][order],false)->copyOn(oldPat[i]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue