sysDef refactor, part 2

to @cam900 and @grauw: you may now pull this to your branch.
check out the comments in sysDef.cpp though.
This commit is contained in:
tildearrow 2022-04-27 00:56:15 -05:00
parent 351c22cb77
commit 24d60507e7
15 changed files with 495 additions and 1644 deletions

View File

@ -212,6 +212,9 @@ size | description
| - 0xb5: tildearrow Sound Unit - 8 channels | - 0xb5: tildearrow Sound Unit - 8 channels
| - 0xde: YM2610B extended - 19 channels | - 0xde: YM2610B extended - 19 channels
| - 0xe0: QSound - 19 channels | - 0xe0: QSound - 19 channels
| - 0xfd: Dummy System - 8 channels
| - 0xfe: reserved for development
| - 0xff: reserved for development
| - (compound!) means that the system is composed of two or more chips, | - (compound!) means that the system is composed of two or more chips,
| and has to be flattened. | and has to be flattened.
32 | sound chip volumes 32 | sound chip volumes
@ -329,6 +332,10 @@ size | description
| - 24: VERA | - 24: VERA
| - 25: X1-010 | - 25: X1-010
| - 26: VRC6 (saw) | - 26: VRC6 (saw)
| - 27: ES5506
| - 28: MultiPCM
| - 29: SNES
| - 30: Sound Unit
1 | reserved 1 | reserved
STR | instrument name STR | instrument name
--- | **FM instrument data** --- | **FM instrument data**

View File

@ -430,9 +430,9 @@ class DivDispatch {
/** /**
* quit the DivDispatch. * quit the DivDispatch.
*/ */
virtual void quit(); virtual void quit();
virtual ~DivDispatch(); virtual ~DivDispatch();
}; };
// pitch calculation: // pitch calculation:

View File

@ -311,6 +311,9 @@ void DivDispatchContainer::init(DivSystem sys, DivEngine* eng, int chanCount, do
case DIV_SYSTEM_MMC5: case DIV_SYSTEM_MMC5:
dispatch=new DivPlatformMMC5; dispatch=new DivPlatformMMC5;
break; break;
case DIV_SYSTEM_DUMMY:
dispatch=new DivPlatformDummy;
break;
default: default:
logW("this system is not supported yet! using dummy platform."); logW("this system is not supported yet! using dummy platform.");
dispatch=new DivPlatformDummy; dispatch=new DivPlatformDummy;

View File

@ -2426,7 +2426,7 @@ bool DivEngine::deinitAudioBackend() {
bool DivEngine::init() { bool DivEngine::init() {
// register systems // register systems
registerSystems(); if (!systemsRegistered) registerSystems();
// init config // init config
#ifdef _WIN32 #ifdef _WIN32

View File

@ -44,8 +44,8 @@
#define BUSY_BEGIN_SOFT softLocked=true; isBusy.lock(); #define BUSY_BEGIN_SOFT softLocked=true; isBusy.lock();
#define BUSY_END isBusy.unlock(); softLocked=false; #define BUSY_END isBusy.unlock(); softLocked=false;
#define DIV_VERSION "dev87" #define DIV_VERSION "dev88"
#define DIV_ENGINE_VERSION 87 #define DIV_ENGINE_VERSION 88
// for imports // for imports
#define DIV_VERSION_MOD 0xff01 #define DIV_VERSION_MOD 0xff01
@ -187,7 +187,7 @@ struct DivSysDef {
unsigned char id_DMF; unsigned char id_DMF;
int channels; int channels;
bool isFM, isSTD, isCompound; bool isFM, isSTD, isCompound;
unsigned char vgmVersion; unsigned int vgmVersion;
const char* chanNames[DIV_MAX_CHANS]; const char* chanNames[DIV_MAX_CHANS];
const char* chanShortNames[DIV_MAX_CHANS]; const char* chanShortNames[DIV_MAX_CHANS];
int chanTypes[DIV_MAX_CHANS]; int chanTypes[DIV_MAX_CHANS];
@ -198,7 +198,7 @@ struct DivSysDef {
EffectProcess postEffectFunc; EffectProcess postEffectFunc;
DivSysDef( DivSysDef(
const char* sysName, const char* sysNameJ, unsigned char fileID, unsigned char fileID_DMF, int chans, const char* sysName, const char* sysNameJ, unsigned char fileID, unsigned char fileID_DMF, int chans,
bool isFMChip, bool isSTDChip, unsigned char vgmVer, bool compound, bool isFMChip, bool isSTDChip, unsigned int vgmVer, bool compound,
std::initializer_list<const char*> chNames, std::initializer_list<const char*> chNames,
std::initializer_list<const char*> chShortNames, std::initializer_list<const char*> chShortNames,
std::initializer_list<int> chTypes, std::initializer_list<int> chTypes,
@ -290,6 +290,7 @@ class DivEngine {
bool skipping; bool skipping;
bool midiIsDirect; bool midiIsDirect;
bool lowLatency; bool lowLatency;
bool systemsRegistered;
int softLockCount; int softLockCount;
int subticks, ticks, curRow, curOrder, remainingLoops, nextSpeed; int subticks, ticks, curRow, curOrder, remainingLoops, nextSpeed;
double divider; double divider;
@ -317,6 +318,8 @@ class DivEngine {
std::vector<String> midiOuts; std::vector<String> midiOuts;
std::vector<DivCommand> cmdStream; std::vector<DivCommand> cmdStream;
DivSysDef* sysDefs[256]; DivSysDef* sysDefs[256];
DivSystem sysFileMapFur[256];
DivSystem sysFileMapDMF[256];
struct SamplePreview { struct SamplePreview {
int sample; int sample;
@ -519,9 +522,6 @@ class DivEngine {
// get sys name // get sys name
const char* getSystemName(DivSystem sys); const char* getSystemName(DivSystem sys);
// get sys chips
const char* getSystemChips(DivSystem sys);
// get japanese system name // get japanese system name
const char* getSystemNameJ(DivSystem sys); const char* getSystemNameJ(DivSystem sys);
@ -850,6 +850,7 @@ class DivEngine {
skipping(false), skipping(false),
midiIsDirect(false), midiIsDirect(false),
lowLatency(false), lowLatency(false),
systemsRegistered(false),
softLockCount(0), softLockCount(0),
subticks(0), subticks(0),
ticks(0), ticks(0),
@ -918,6 +919,11 @@ class DivEngine {
memset(reversePitchTable,0,4096*sizeof(int)); memset(reversePitchTable,0,4096*sizeof(int));
memset(pitchTable,0,4096*sizeof(int)); memset(pitchTable,0,4096*sizeof(int));
memset(sysDefs,0,256*sizeof(void*)); memset(sysDefs,0,256*sizeof(void*));
for (int i=0; i<256; i++) {
sysFileMapFur[i]=DIV_SYSTEM_NULL;
sysFileMapDMF[i]=DIV_SYSTEM_NULL;
}
} }
}; };
#endif #endif

View File

@ -1101,9 +1101,11 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
return false; return false;
} }
logD("systems:");
for (int i=0; i<32; i++) { for (int i=0; i<32; i++) {
unsigned char sysID=reader.readC(); unsigned char sysID=reader.readC();
ds.system[i]=systemFromFileFur(sysID); ds.system[i]=systemFromFileFur(sysID);
logD("- %d: %.2x (%s)",i,sysID,getSystemName(ds.system[i]));
if (sysID!=0 && systemToFileFur(ds.system[i])==0) { if (sysID!=0 && systemToFileFur(ds.system[i])==0) {
logE("unrecognized system ID %.2x",ds.system[i]); logE("unrecognized system ID %.2x",ds.system[i]);
lastError=fmt::sprintf("unrecognized system ID %.2x!",ds.system[i]); lastError=fmt::sprintf("unrecognized system ID %.2x!",ds.system[i]);
@ -2023,6 +2025,8 @@ bool DivEngine::load(unsigned char* f, size_t slen) {
return false; return false;
} }
if (!systemsRegistered) registerSystems();
// step 1: try loading as a zlib-compressed file // step 1: try loading as a zlib-compressed file
logD("trying zlib..."); logD("trying zlib...");
try { try {

View File

@ -54,7 +54,12 @@ enum DivInstrumentType: unsigned short {
DIV_INS_VERA=24, DIV_INS_VERA=24,
DIV_INS_X1_010=25, DIV_INS_X1_010=25,
DIV_INS_VRC6_SAW=26, DIV_INS_VRC6_SAW=26,
DIV_INS_ES5506=27,
DIV_INS_MULTIPCM=28,
DIV_INS_SNES=29,
DIV_INS_SU=30,
DIV_INS_MAX, DIV_INS_MAX,
DIV_INS_NULL
}; };
// FM operator structure: // FM operator structure:

View File

@ -22,15 +22,20 @@
#include <stdio.h> #include <stdio.h>
#include <math.h> #include <math.h>
#define CHIP_FREQBASE 2048
void DivPlatformDummy::acquire(short* bufL, short* bufR, size_t start, size_t len) { void DivPlatformDummy::acquire(short* bufL, short* bufR, size_t start, size_t len) {
for (size_t i=start; i<start+len; i++) { for (size_t i=start; i<start+len; i++) {
bufL[i]=0; int out=0;
for (unsigned char j=0; j<chans; j++) { for (unsigned char j=0; j<chans; j++) {
if (chan[j].active) { if (chan[j].active) {
if (!isMuted[j]) bufL[i]+=(((signed short)chan[j].pos)*chan[j].amp*chan[j].vol)>>13; if (!isMuted[j]) out+=(((signed short)chan[j].pos)*chan[j].amp*chan[j].vol)>>12;
chan[j].pos+=chan[j].freq; chan[j].pos+=chan[j].freq;
} }
} }
if (out<-32768) out=-32768;
if (out>32767) out=32767;
bufL[i]=out;
} }
} }
@ -41,8 +46,8 @@ void DivPlatformDummy::muteChannel(int ch, bool mute) {
void DivPlatformDummy::tick(bool sysTick) { void DivPlatformDummy::tick(bool sysTick) {
for (unsigned char i=0; i<chans; i++) { for (unsigned char i=0; i<chans; i++) {
if (sysTick) { if (sysTick) {
chan[i].amp-=3; chan[i].amp-=7;
if (chan[i].amp<16) chan[i].amp=16; if (chan[i].amp<15) chan[i].amp=15;
} }
if (chan[i].freqChanged) { if (chan[i].freqChanged) {
@ -60,7 +65,7 @@ int DivPlatformDummy::dispatch(DivCommand c) {
switch (c.cmd) { switch (c.cmd) {
case DIV_CMD_NOTE_ON: case DIV_CMD_NOTE_ON:
if (c.value!=DIV_NOTE_NULL) { if (c.value!=DIV_NOTE_NULL) {
chan[c.chan].baseFreq=65.6f*pow(2.0f,((float)c.value/12.0f)); chan[c.chan].baseFreq=NOTE_FREQUENCY(c.value);
chan[c.chan].freqChanged=true; chan[c.chan].freqChanged=true;
} }
chan[c.chan].active=true; chan[c.chan].active=true;
@ -80,8 +85,28 @@ int DivPlatformDummy::dispatch(DivCommand c) {
chan[c.chan].pitch=c.value; chan[c.chan].pitch=c.value;
chan[c.chan].freqChanged=true; chan[c.chan].freqChanged=true;
break; break;
case DIV_CMD_NOTE_PORTA: {
int destFreq=NOTE_FREQUENCY(c.value2);
bool return2=false;
if (destFreq>chan[c.chan].baseFreq) {
chan[c.chan].baseFreq+=c.value;
if (chan[c.chan].baseFreq>=destFreq) {
chan[c.chan].baseFreq=destFreq;
return2=true;
}
} else {
chan[c.chan].baseFreq-=c.value;
if (chan[c.chan].baseFreq<=destFreq) {
chan[c.chan].baseFreq=destFreq;
return2=true;
}
}
chan[c.chan].freqChanged=true;
if (return2) return 2;
break;
}
case DIV_CMD_LEGATO: case DIV_CMD_LEGATO:
chan[c.chan].baseFreq=65.6f*pow(2.0f,((float)c.value/12.0f)); chan[c.chan].baseFreq=NOTE_FREQUENCY(c.value);
chan[c.chan].freqChanged=true; chan[c.chan].freqChanged=true;
break; break;
case DIV_CMD_GET_VOLMAX: case DIV_CMD_GET_VOLMAX:
@ -108,6 +133,7 @@ int DivPlatformDummy::init(DivEngine* p, int channels, int sugRate, unsigned int
isMuted[i]=false; isMuted[i]=false;
} }
rate=65536; rate=65536;
chipClock=65536;
chans=channels; chans=channels;
reset(); reset();
return channels; return channels;

View File

@ -23,8 +23,7 @@
// used when a DivDispatch for a system is not found. // used when a DivDispatch for a system is not found.
class DivPlatformDummy: public DivDispatch { class DivPlatformDummy: public DivDispatch {
struct Channel { struct Channel {
unsigned short freq, baseFreq; int freq, baseFreq, pitch;
short pitch;
unsigned short pos; unsigned short pos;
bool active, freqChanged; bool active, freqChanged;
unsigned char vol; unsigned char vol;

File diff suppressed because it is too large Load Diff

View File

@ -187,6 +187,22 @@ void FurnaceGUI::drawInsList() {
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_INSTR_X1_010]); ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_INSTR_X1_010]);
name=fmt::sprintf(ICON_FA_BAR_CHART " %.2X: %s##_INS%d",i,ins->name,i); name=fmt::sprintf(ICON_FA_BAR_CHART " %.2X: %s##_INS%d",i,ins->name,i);
break; break;
case DIV_INS_ES5506:
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_INSTR_ES5506]);
name=fmt::sprintf(ICON_FA_VOLUME_UP " %.2X: %s##_INS%d",i,ins->name,i);
break;
case DIV_INS_MULTIPCM:
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_INSTR_MULTIPCM]);
name=fmt::sprintf(ICON_FA_VOLUME_UP " %.2X: %s##_INS%d",i,ins->name,i);
break;
case DIV_INS_SNES:
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_INSTR_SNES]);
name=fmt::sprintf(ICON_FA_VOLUME_UP " %.2X: %s##_INS%d",i,ins->name,i);
break;
case DIV_INS_SU:
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_INSTR_SU]);
name=fmt::sprintf(ICON_FA_MICROCHIP " %.2X: %s##_INS%d",i,ins->name,i);
break;
default: default:
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_INSTR_UNKNOWN]); ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_INSTR_UNKNOWN]);
name=fmt::sprintf(ICON_FA_QUESTION " %.2X: %s##_INS%d",i,ins->name,i); name=fmt::sprintf(ICON_FA_QUESTION " %.2X: %s##_INS%d",i,ins->name,i);

View File

@ -505,9 +505,11 @@ bool FurnaceGUI::CWVSliderInt(const char* label, const ImVec2& size, int* v, int
} }
const char* FurnaceGUI::getSystemName(DivSystem which) { const char* FurnaceGUI::getSystemName(DivSystem which) {
/*
if (settings.chipNames) { if (settings.chipNames) {
return e->getSystemChips(which); return e->getSystemChips(which);
} }
*/
return e->getSystemName(which); return e->getSystemName(which);
} }
@ -2670,7 +2672,7 @@ bool FurnaceGUI::loop() {
ImGui::Separator(); ImGui::Separator();
if (ImGui::BeginMenu("add system...")) { if (ImGui::BeginMenu("add system...")) {
for (int j=0; availableSystems[j]; j++) { for (int j=0; availableSystems[j]; j++) {
if (!settings.hiddenSystems && availableSystems[j]==DIV_SYSTEM_YMU759) continue; if (!settings.hiddenSystems && (availableSystems[j]==DIV_SYSTEM_YMU759 || availableSystems[j]==DIV_SYSTEM_DUMMY || availableSystems[j]==DIV_SYSTEM_SOUND_UNIT)) continue;
sysAddOption((DivSystem)availableSystems[j]); sysAddOption((DivSystem)availableSystems[j]);
} }
ImGui::EndMenu(); ImGui::EndMenu();
@ -2688,7 +2690,7 @@ bool FurnaceGUI::loop() {
for (int i=0; i<e->song.systemLen; i++) { for (int i=0; i<e->song.systemLen; i++) {
if (ImGui::BeginMenu(fmt::sprintf("%d. %s##_SYSC%d",i+1,getSystemName(e->song.system[i]),i).c_str())) { if (ImGui::BeginMenu(fmt::sprintf("%d. %s##_SYSC%d",i+1,getSystemName(e->song.system[i]),i).c_str())) {
for (int j=0; availableSystems[j]; j++) { for (int j=0; availableSystems[j]; j++) {
if (!settings.hiddenSystems && availableSystems[j]==DIV_SYSTEM_YMU759) continue; if (!settings.hiddenSystems && (availableSystems[j]==DIV_SYSTEM_YMU759 || availableSystems[j]==DIV_SYSTEM_DUMMY || availableSystems[j]==DIV_SYSTEM_SOUND_UNIT)) continue;
sysChangeOption(i,(DivSystem)availableSystems[j]); sysChangeOption(i,(DivSystem)availableSystems[j]);
} }
ImGui::EndMenu(); ImGui::EndMenu();

View File

@ -145,6 +145,10 @@ enum FurnaceGUIColors {
GUI_COLOR_INSTR_VERA, GUI_COLOR_INSTR_VERA,
GUI_COLOR_INSTR_X1_010, GUI_COLOR_INSTR_X1_010,
GUI_COLOR_INSTR_VRC6_SAW, GUI_COLOR_INSTR_VRC6_SAW,
GUI_COLOR_INSTR_ES5506,
GUI_COLOR_INSTR_MULTIPCM,
GUI_COLOR_INSTR_SNES,
GUI_COLOR_INSTR_SU,
GUI_COLOR_INSTR_UNKNOWN, GUI_COLOR_INSTR_UNKNOWN,
GUI_COLOR_CHANNEL_FM, GUI_COLOR_CHANNEL_FM,

View File

@ -106,7 +106,11 @@ const char* insTypes[DIV_INS_MAX]={
"Atari Lynx", "Atari Lynx",
"VERA", "VERA",
"X1-010", "X1-010",
"VRC6 (saw)" "VRC6 (saw)",
"ES5506",
"MultiPCM",
"SNES",
"Sound Unit",
}; };
const char* sampleDepths[17]={ const char* sampleDepths[17]={
@ -509,6 +513,10 @@ const FurnaceGUIColorDef guiColors[GUI_COLOR_MAX]={
D(GUI_COLOR_INSTR_VERA,"",ImVec4(0.4f,0.6f,1.0f,1.0f)), D(GUI_COLOR_INSTR_VERA,"",ImVec4(0.4f,0.6f,1.0f,1.0f)),
D(GUI_COLOR_INSTR_X1_010,"",ImVec4(0.3f,0.5f,1.0f,1.0f)), D(GUI_COLOR_INSTR_X1_010,"",ImVec4(0.3f,0.5f,1.0f,1.0f)),
D(GUI_COLOR_INSTR_VRC6_SAW,"",ImVec4(0.8f,0.3f,0.0f,1.0f)), D(GUI_COLOR_INSTR_VRC6_SAW,"",ImVec4(0.8f,0.3f,0.0f,1.0f)),
D(GUI_COLOR_INSTR_ES5506,"",ImVec4(0.5f,0.5f,1.0f,1.0f)),
D(GUI_COLOR_INSTR_MULTIPCM,"",ImVec4(1.0f,0.8f,0.1f,1.0f)),
D(GUI_COLOR_INSTR_SNES,"",ImVec4(0.8f,0.7f,1.0f,1.0f)),
D(GUI_COLOR_INSTR_SU,"",ImVec4(0.95f,0.98f,1.0f,1.0f)),
D(GUI_COLOR_INSTR_UNKNOWN,"",ImVec4(0.3f,0.3f,0.3f,1.0f)), D(GUI_COLOR_INSTR_UNKNOWN,"",ImVec4(0.3f,0.3f,0.3f,1.0f)),
D(GUI_COLOR_CHANNEL_FM,"",ImVec4(0.2f,0.8f,1.0f,1.0f)), D(GUI_COLOR_CHANNEL_FM,"",ImVec4(0.2f,0.8f,1.0f,1.0f)),
@ -588,6 +596,8 @@ const int availableSystems[]={
DIV_SYSTEM_AMIGA, DIV_SYSTEM_AMIGA,
DIV_SYSTEM_PCSPKR, DIV_SYSTEM_PCSPKR,
DIV_SYSTEM_YMU759, DIV_SYSTEM_YMU759,
DIV_SYSTEM_DUMMY,
DIV_SYSTEM_SOUND_UNIT,
DIV_SYSTEM_OPLL, DIV_SYSTEM_OPLL,
DIV_SYSTEM_OPLL_DRUMS, DIV_SYSTEM_OPLL_DRUMS,
DIV_SYSTEM_VRC7, DIV_SYSTEM_VRC7,

View File

@ -1174,6 +1174,10 @@ void FurnaceGUI::drawSettings() {
UI_COLOR_CONFIG(GUI_COLOR_INSTR_MIKEY,"Lynx"); UI_COLOR_CONFIG(GUI_COLOR_INSTR_MIKEY,"Lynx");
UI_COLOR_CONFIG(GUI_COLOR_INSTR_VERA,"VERA"); UI_COLOR_CONFIG(GUI_COLOR_INSTR_VERA,"VERA");
UI_COLOR_CONFIG(GUI_COLOR_INSTR_X1_010,"X1-010"); UI_COLOR_CONFIG(GUI_COLOR_INSTR_X1_010,"X1-010");
UI_COLOR_CONFIG(GUI_COLOR_INSTR_ES5506,"ES5506");
UI_COLOR_CONFIG(GUI_COLOR_INSTR_MULTIPCM,"MultiPCM");
UI_COLOR_CONFIG(GUI_COLOR_INSTR_SNES,"SNES");
UI_COLOR_CONFIG(GUI_COLOR_INSTR_SU,"Sound Unit");
UI_COLOR_CONFIG(GUI_COLOR_INSTR_UNKNOWN,"Other/Unknown"); UI_COLOR_CONFIG(GUI_COLOR_INSTR_UNKNOWN,"Other/Unknown");
ImGui::TreePop(); ImGui::TreePop();
} }