Add emulation settings for YRW801, TG100 and MU5 sample ROMs.

This commit is contained in:
Laurens Holst 2022-05-11 23:39:36 +02:00
parent 05af3c147a
commit c29f18dfc2
5 changed files with 170 additions and 3 deletions

View file

@ -491,6 +491,77 @@ void DivEngine::notifyWaveChange(int wave) {
BUSY_END;
}
int DivEngine::loadSampleRom(String path, ssize_t expectedSize, unsigned char*& ret) {
ret = NULL;
if (path.empty()) {
return 0;
}
logI("loading ROM %s...",path);
FILE* f=ps_fopen(path.c_str(),"rb");
if (f==NULL) {
logE("error: %s",strerror(errno));
lastError=strerror(errno);
return -1;
}
if (fseek(f,0,SEEK_END)<0) {
logE("size error: %s",strerror(errno));
lastError=fmt::sprintf("on seek: %s",strerror(errno));
fclose(f);
return -1;
}
ssize_t len=ftell(f);
if (len==(SIZE_MAX>>1)) {
logE("could not get file length: %s",strerror(errno));
lastError=fmt::sprintf("on pre tell: %s",strerror(errno));
fclose(f);
return -1;
}
if (len<1) {
if (len==0) {
logE("that file is empty!");
lastError="file is empty";
} else {
logE("tell error: %s",strerror(errno));
lastError=fmt::sprintf("on tell: %s",strerror(errno));
}
fclose(f);
return -1;
}
if (len!=expectedSize) {
logE("ROM size mismatch, expected: %d bytes, was: %d bytes", expectedSize, len);
lastError=fmt::sprintf("ROM size mismatch, expected: %d bytes, was: %d", expectedSize, len);
return -1;
}
if (fseek(f,0,SEEK_SET)<0) {
logE("size error: %s",strerror(errno));
lastError=fmt::sprintf("on get size: %s",strerror(errno));
fclose(f);
return -1;
}
unsigned char* file=new unsigned char[len];
if (fread(file,1,(size_t)len,f)!=(size_t)len) {
logE("read error: %s",strerror(errno));
lastError=fmt::sprintf("on read: %s",strerror(errno));
fclose(f);
delete[] file;
return -1;
}
fclose(f);
ret = file;
return 0;
}
int DivEngine::loadSampleRoms() {
delete[] yrw801Rom;
delete[] tg100Rom;
delete[] mu5Rom;
int error = 0;
error += loadSampleRom(getConfString("yrw801Path",""), 0x200000, yrw801Rom);
error += loadSampleRom(getConfString("tg100Path",""), 0x200000, tg100Rom);
error += loadSampleRom(getConfString("mu5Path",""), 0x200000, mu5Rom);
return error;
}
void DivEngine::renderSamplesP() {
BUSY_BEGIN;
renderSamples();
@ -2662,6 +2733,8 @@ bool DivEngine::init() {
loadConf();
loadSampleRoms();
// set default system preset
if (!hasLoadedSomething) {
logD("setting default preset");
@ -2735,5 +2808,8 @@ bool DivEngine::quit() {
active=false;
delete[] oscBuf[0];
delete[] oscBuf[1];
delete[] yrw801Rom;
delete[] tg100Rom;
delete[] mu5Rom;
return true;
}

View file

@ -397,6 +397,8 @@ class DivEngine {
void loadOPM(SafeReader& reader, std::vector<DivInstrument*>& ret, String& stripPath);
void loadFF(SafeReader& reader, std::vector<DivInstrument*>& ret, String& stripPath);
int loadSampleRom(String path, ssize_t expectedSize, unsigned char*& ret);
bool initAudioBackend();
bool deinitAudioBackend();
@ -783,6 +785,9 @@ class DivEngine {
// get register cheatsheet
const char** getRegisterSheet(int sys);
// load sample ROMs
int loadSampleRoms();
// UNSAFE render samples - only execute when locked
void renderSamples();
@ -853,6 +858,10 @@ class DivEngine {
// terminate the engine.
bool quit();
unsigned char* yrw801Rom;
unsigned char* tg100Rom;
unsigned char* mu5Rom;
DivEngine():
output(NULL),
exportThread(NULL),
@ -927,7 +936,10 @@ class DivEngine {
oscReadPos(0),
oscWritePos(0),
tickMult(1),
processTime(0) {
processTime(0),
yrw801Rom(NULL),
tg100Rom(NULL),
mu5Rom(NULL) {
memset(isMuted,0,DIV_MAX_CHANS*sizeof(bool));
memset(keyHit,0,DIV_MAX_CHANS*sizeof(bool));
memset(dispatchChanOfChan,0,DIV_MAX_CHANS*sizeof(int));

View file

@ -1501,6 +1501,19 @@ void FurnaceGUI::openFileDialog(FurnaceGUIFileDialogs type) {
dpiScale
);
break;
case GUI_FILE_YRW801_ROM_OPEN:
case GUI_FILE_TG100_ROM_OPEN:
case GUI_FILE_MU5_ROM_OPEN:
if (!dirExists(workingDirSample)) workingDirSample=getHomeDir();
hasOpened=fileDialog->openLoad(
"Load ROM",
{"compatible files", "*.rom *.bin",
"all files", ".*"},
"compatible files{.rom,.bin},.*",
workingDirRom,
dpiScale
);
break;
}
if (hasOpened) curFileDialog=type;
//ImGui::GetIO().ConfigFlags|=ImGuiConfigFlags_NavEnableKeyboard;
@ -2983,6 +2996,11 @@ bool FurnaceGUI::loop() {
case GUI_FILE_EXPORT_LAYOUT:
workingDirLayout=fileDialog->getPath()+DIR_SEPARATOR_STR;
break;
case GUI_FILE_YRW801_ROM_OPEN:
case GUI_FILE_TG100_ROM_OPEN:
case GUI_FILE_MU5_ROM_OPEN:
workingDirRom=fileDialog->getPath()+DIR_SEPARATOR_STR;
break;
}
if (fileDialog->accepted()) {
fileName=fileDialog->getFileName();
@ -3196,6 +3214,15 @@ bool FurnaceGUI::loop() {
case GUI_FILE_EXPORT_LAYOUT:
exportLayout(copyOfName);
break;
case GUI_FILE_YRW801_ROM_OPEN:
settings.yrw801Path=copyOfName;
break;
case GUI_FILE_TG100_ROM_OPEN:
settings.tg100Path=copyOfName;
break;
case GUI_FILE_MU5_ROM_OPEN:
settings.mu5Path=copyOfName;
break;
}
curFileDialog=GUI_FILE_OPEN;
}

View file

@ -257,7 +257,10 @@ enum FurnaceGUIFileDialogs {
GUI_FILE_IMPORT_LAYOUT,
GUI_FILE_EXPORT_COLORS,
GUI_FILE_EXPORT_KEYBINDS,
GUI_FILE_EXPORT_LAYOUT
GUI_FILE_EXPORT_LAYOUT,
GUI_FILE_YRW801_ROM_OPEN,
GUI_FILE_TG100_ROM_OPEN,
GUI_FILE_MU5_ROM_OPEN
};
enum FurnaceGUIWarnings {
@ -734,7 +737,7 @@ class FurnaceGUI {
bool updateSampleTex;
String workingDir, fileName, clipboard, warnString, errorString, lastError, curFileName, nextFile;
String workingDirSong, workingDirIns, workingDirWave, workingDirSample, workingDirAudioExport, workingDirVGMExport, workingDirFont, workingDirColors, workingDirKeybinds, workingDirLayout;
String workingDirSong, workingDirIns, workingDirWave, workingDirSample, workingDirAudioExport, workingDirVGMExport, workingDirFont, workingDirColors, workingDirKeybinds, workingDirLayout, workingDirRom;
String mmlString[17];
String mmlStringW;
@ -792,6 +795,9 @@ class FurnaceGUI {
int saaCore;
int nesCore;
int fdsCore;
String yrw801Path;
String tg100Path;
String mu5Path;
int mainFont;
int patFont;
int audioRate;
@ -879,6 +885,9 @@ class FurnaceGUI {
saaCore(1),
nesCore(0),
fdsCore(0),
yrw801Path(""),
tg100Path(""),
mu5Path(""),
mainFont(0),
patFont(0),
audioRate(44100),

View file

@ -887,6 +887,33 @@ void FurnaceGUI::drawSettings() {
ImGui::Text("FDS core");
ImGui::SameLine();
ImGui::Combo("##FDSCore",&settings.fdsCore,nesCores,2);
ImGui::Separator();
ImGui::Text("Sample ROMs:");
ImGui::Text("OPL4 YRW801 path");
ImGui::SameLine();
ImGui::InputText("##YRW801Path",&settings.yrw801Path);
ImGui::SameLine();
if (ImGui::Button(ICON_FA_FOLDER "##YRW801Load")) {
openFileDialog(GUI_FILE_YRW801_ROM_OPEN);
}
ImGui::Text("MultiPCM TG100 path");
ImGui::SameLine();
ImGui::InputText("##TG100Path",&settings.tg100Path);
ImGui::SameLine();
if (ImGui::Button(ICON_FA_FOLDER "##TG100Load")) {
openFileDialog(GUI_FILE_TG100_ROM_OPEN);
}
ImGui::Text("MultiPCM MU5 path");
ImGui::SameLine();
ImGui::InputText("##MU5Path",&settings.mu5Path);
ImGui::SameLine();
if (ImGui::Button(ICON_FA_FOLDER "##MU5Load")) {
openFileDialog(GUI_FILE_MU5_ROM_OPEN);
}
}
ImGui::EndChild();
ImGui::EndTabItem();
@ -1789,6 +1816,9 @@ void FurnaceGUI::syncSettings() {
settings.saaCore=e->getConfInt("saaCore",1);
settings.nesCore=e->getConfInt("nesCore",0);
settings.fdsCore=e->getConfInt("fdsCore",0);
settings.yrw801Path=e->getConfString("yrw801Path","");
settings.tg100Path=e->getConfString("tg100Path","");
settings.mu5Path=e->getConfString("mu5Path","");
settings.mainFont=e->getConfInt("mainFont",0);
settings.patFont=e->getConfInt("patFont",0);
settings.mainFontPath=e->getConfString("mainFontPath","");
@ -1960,6 +1990,10 @@ void FurnaceGUI::syncSettings() {
}
void FurnaceGUI::commitSettings() {
bool sampleRomsChanged = settings.yrw801Path!=e->getConfString("yrw801Path","") ||
settings.tg100Path!=e->getConfString("tg100Path","") ||
settings.mu5Path!=e->getConfString("mu5Path","");
e->setConf("mainFontSize",settings.mainFontSize);
e->setConf("patFontSize",settings.patFontSize);
e->setConf("iconSize",settings.iconSize);
@ -1975,6 +2009,9 @@ void FurnaceGUI::commitSettings() {
e->setConf("saaCore",settings.saaCore);
e->setConf("nesCore",settings.nesCore);
e->setConf("fdsCore",settings.fdsCore);
e->setConf("yrw801Path",settings.yrw801Path);
e->setConf("tg100Path",settings.tg100Path);
e->setConf("mu5Path",settings.mu5Path);
e->setConf("mainFont",settings.mainFont);
e->setConf("patFont",settings.patFont);
e->setConf("mainFontPath",settings.mainFontPath);
@ -2063,6 +2100,12 @@ void FurnaceGUI::commitSettings() {
e->saveConf();
if (sampleRomsChanged) {
if (e->loadSampleRoms()) {
showError(e->getLastError());
}
}
if (!e->switchMaster()) {
showError("could not initialize audio!");
}