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
| - 0xde: YM2610B extended - 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,
| and has to be flattened.
32 | sound chip volumes
@ -329,6 +332,10 @@ size | description
| - 24: VERA
| - 25: X1-010
| - 26: VRC6 (saw)
| - 27: ES5506
| - 28: MultiPCM
| - 29: SNES
| - 30: Sound Unit
1 | reserved
STR | instrument name
--- | **FM instrument data**

View file

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

View file

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

View file

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

View file

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

View file

@ -1101,9 +1101,11 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
return false;
}
logD("systems:");
for (int i=0; i<32; i++) {
unsigned char sysID=reader.readC();
ds.system[i]=systemFromFileFur(sysID);
logD("- %d: %.2x (%s)",i,sysID,getSystemName(ds.system[i]));
if (sysID!=0 && systemToFileFur(ds.system[i])==0) {
logE("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;
}
if (!systemsRegistered) registerSystems();
// step 1: try loading as a zlib-compressed file
logD("trying zlib...");
try {

View file

@ -54,7 +54,12 @@ enum DivInstrumentType: unsigned short {
DIV_INS_VERA=24,
DIV_INS_X1_010=25,
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_NULL
};
// FM operator structure:

View file

@ -22,15 +22,20 @@
#include <stdio.h>
#include <math.h>
#define CHIP_FREQBASE 2048
void DivPlatformDummy::acquire(short* bufL, short* bufR, size_t start, size_t len) {
for (size_t i=start; i<start+len; i++) {
bufL[i]=0;
int out=0;
for (unsigned char j=0; j<chans; j++) {
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;
}
}
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) {
for (unsigned char i=0; i<chans; i++) {
if (sysTick) {
chan[i].amp-=3;
if (chan[i].amp<16) chan[i].amp=16;
chan[i].amp-=7;
if (chan[i].amp<15) chan[i].amp=15;
}
if (chan[i].freqChanged) {
@ -60,7 +65,7 @@ int DivPlatformDummy::dispatch(DivCommand c) {
switch (c.cmd) {
case DIV_CMD_NOTE_ON:
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].active=true;
@ -80,8 +85,28 @@ int DivPlatformDummy::dispatch(DivCommand c) {
chan[c.chan].pitch=c.value;
chan[c.chan].freqChanged=true;
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:
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;
break;
case DIV_CMD_GET_VOLMAX:
@ -108,6 +133,7 @@ int DivPlatformDummy::init(DivEngine* p, int channels, int sugRate, unsigned int
isMuted[i]=false;
}
rate=65536;
chipClock=65536;
chans=channels;
reset();
return channels;

View file

@ -23,8 +23,7 @@
// used when a DivDispatch for a system is not found.
class DivPlatformDummy: public DivDispatch {
struct Channel {
unsigned short freq, baseFreq;
short pitch;
int freq, baseFreq, pitch;
unsigned short pos;
bool active, freqChanged;
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]);
name=fmt::sprintf(ICON_FA_BAR_CHART " %.2X: %s##_INS%d",i,ins->name,i);
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:
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_INSTR_UNKNOWN]);
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) {
/*
if (settings.chipNames) {
return e->getSystemChips(which);
}
*/
return e->getSystemName(which);
}
@ -2670,7 +2672,7 @@ bool FurnaceGUI::loop() {
ImGui::Separator();
if (ImGui::BeginMenu("add system...")) {
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]);
}
ImGui::EndMenu();
@ -2688,7 +2690,7 @@ bool FurnaceGUI::loop() {
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())) {
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]);
}
ImGui::EndMenu();

View file

@ -145,6 +145,10 @@ enum FurnaceGUIColors {
GUI_COLOR_INSTR_VERA,
GUI_COLOR_INSTR_X1_010,
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_CHANNEL_FM,

View file

@ -106,7 +106,11 @@ const char* insTypes[DIV_INS_MAX]={
"Atari Lynx",
"VERA",
"X1-010",
"VRC6 (saw)"
"VRC6 (saw)",
"ES5506",
"MultiPCM",
"SNES",
"Sound Unit",
};
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_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_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_CHANNEL_FM,"",ImVec4(0.2f,0.8f,1.0f,1.0f)),
@ -588,6 +596,8 @@ const int availableSystems[]={
DIV_SYSTEM_AMIGA,
DIV_SYSTEM_PCSPKR,
DIV_SYSTEM_YMU759,
DIV_SYSTEM_DUMMY,
DIV_SYSTEM_SOUND_UNIT,
DIV_SYSTEM_OPLL,
DIV_SYSTEM_OPLL_DRUMS,
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_VERA,"VERA");
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");
ImGui::TreePop();
}