mirror of
https://github.com/tildearrow/furnace.git
synced 2024-11-15 17:25:06 +00:00
Merge pull request #448 from grauw/sample-rom-settings
Add emulation settings for YRW801, TG100 and MU5 sample ROMs.
This commit is contained in:
commit
9bac00efe5
5 changed files with 170 additions and 3 deletions
|
@ -491,6 +491,77 @@ void DivEngine::notifyWaveChange(int wave) {
|
||||||
BUSY_END;
|
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() {
|
void DivEngine::renderSamplesP() {
|
||||||
BUSY_BEGIN;
|
BUSY_BEGIN;
|
||||||
renderSamples();
|
renderSamples();
|
||||||
|
@ -2708,6 +2779,8 @@ bool DivEngine::init() {
|
||||||
|
|
||||||
loadConf();
|
loadConf();
|
||||||
|
|
||||||
|
loadSampleRoms();
|
||||||
|
|
||||||
// set default system preset
|
// set default system preset
|
||||||
if (!hasLoadedSomething) {
|
if (!hasLoadedSomething) {
|
||||||
logD("setting default preset");
|
logD("setting default preset");
|
||||||
|
@ -2781,5 +2854,8 @@ bool DivEngine::quit() {
|
||||||
active=false;
|
active=false;
|
||||||
delete[] oscBuf[0];
|
delete[] oscBuf[0];
|
||||||
delete[] oscBuf[1];
|
delete[] oscBuf[1];
|
||||||
|
delete[] yrw801Rom;
|
||||||
|
delete[] tg100Rom;
|
||||||
|
delete[] mu5Rom;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -397,6 +397,8 @@ class DivEngine {
|
||||||
void loadOPM(SafeReader& reader, std::vector<DivInstrument*>& ret, String& stripPath);
|
void loadOPM(SafeReader& reader, std::vector<DivInstrument*>& ret, String& stripPath);
|
||||||
void loadFF(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 initAudioBackend();
|
||||||
bool deinitAudioBackend();
|
bool deinitAudioBackend();
|
||||||
|
|
||||||
|
@ -783,6 +785,9 @@ class DivEngine {
|
||||||
// get register cheatsheet
|
// get register cheatsheet
|
||||||
const char** getRegisterSheet(int sys);
|
const char** getRegisterSheet(int sys);
|
||||||
|
|
||||||
|
// load sample ROMs
|
||||||
|
int loadSampleRoms();
|
||||||
|
|
||||||
// UNSAFE render samples - only execute when locked
|
// UNSAFE render samples - only execute when locked
|
||||||
void renderSamples();
|
void renderSamples();
|
||||||
|
|
||||||
|
@ -856,6 +861,10 @@ class DivEngine {
|
||||||
// terminate the engine.
|
// terminate the engine.
|
||||||
bool quit();
|
bool quit();
|
||||||
|
|
||||||
|
unsigned char* yrw801Rom;
|
||||||
|
unsigned char* tg100Rom;
|
||||||
|
unsigned char* mu5Rom;
|
||||||
|
|
||||||
DivEngine():
|
DivEngine():
|
||||||
output(NULL),
|
output(NULL),
|
||||||
exportThread(NULL),
|
exportThread(NULL),
|
||||||
|
@ -930,7 +939,10 @@ class DivEngine {
|
||||||
oscReadPos(0),
|
oscReadPos(0),
|
||||||
oscWritePos(0),
|
oscWritePos(0),
|
||||||
tickMult(1),
|
tickMult(1),
|
||||||
processTime(0) {
|
processTime(0),
|
||||||
|
yrw801Rom(NULL),
|
||||||
|
tg100Rom(NULL),
|
||||||
|
mu5Rom(NULL) {
|
||||||
memset(isMuted,0,DIV_MAX_CHANS*sizeof(bool));
|
memset(isMuted,0,DIV_MAX_CHANS*sizeof(bool));
|
||||||
memset(keyHit,0,DIV_MAX_CHANS*sizeof(bool));
|
memset(keyHit,0,DIV_MAX_CHANS*sizeof(bool));
|
||||||
memset(dispatchChanOfChan,0,DIV_MAX_CHANS*sizeof(int));
|
memset(dispatchChanOfChan,0,DIV_MAX_CHANS*sizeof(int));
|
||||||
|
|
|
@ -1507,6 +1507,19 @@ void FurnaceGUI::openFileDialog(FurnaceGUIFileDialogs type) {
|
||||||
dpiScale
|
dpiScale
|
||||||
);
|
);
|
||||||
break;
|
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;
|
if (hasOpened) curFileDialog=type;
|
||||||
//ImGui::GetIO().ConfigFlags|=ImGuiConfigFlags_NavEnableKeyboard;
|
//ImGui::GetIO().ConfigFlags|=ImGuiConfigFlags_NavEnableKeyboard;
|
||||||
|
@ -3024,6 +3037,11 @@ bool FurnaceGUI::loop() {
|
||||||
case GUI_FILE_EXPORT_LAYOUT:
|
case GUI_FILE_EXPORT_LAYOUT:
|
||||||
workingDirLayout=fileDialog->getPath()+DIR_SEPARATOR_STR;
|
workingDirLayout=fileDialog->getPath()+DIR_SEPARATOR_STR;
|
||||||
break;
|
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()) {
|
if (fileDialog->accepted()) {
|
||||||
fileName=fileDialog->getFileName();
|
fileName=fileDialog->getFileName();
|
||||||
|
@ -3237,6 +3255,15 @@ bool FurnaceGUI::loop() {
|
||||||
case GUI_FILE_EXPORT_LAYOUT:
|
case GUI_FILE_EXPORT_LAYOUT:
|
||||||
exportLayout(copyOfName);
|
exportLayout(copyOfName);
|
||||||
break;
|
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;
|
curFileDialog=GUI_FILE_OPEN;
|
||||||
}
|
}
|
||||||
|
|
|
@ -257,7 +257,10 @@ enum FurnaceGUIFileDialogs {
|
||||||
GUI_FILE_IMPORT_LAYOUT,
|
GUI_FILE_IMPORT_LAYOUT,
|
||||||
GUI_FILE_EXPORT_COLORS,
|
GUI_FILE_EXPORT_COLORS,
|
||||||
GUI_FILE_EXPORT_KEYBINDS,
|
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 {
|
enum FurnaceGUIWarnings {
|
||||||
|
@ -765,7 +768,7 @@ class FurnaceGUI {
|
||||||
bool updateSampleTex;
|
bool updateSampleTex;
|
||||||
|
|
||||||
String workingDir, fileName, clipboard, warnString, errorString, lastError, curFileName, nextFile;
|
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 mmlString[17];
|
||||||
String mmlStringW;
|
String mmlStringW;
|
||||||
|
|
||||||
|
@ -823,6 +826,9 @@ class FurnaceGUI {
|
||||||
int saaCore;
|
int saaCore;
|
||||||
int nesCore;
|
int nesCore;
|
||||||
int fdsCore;
|
int fdsCore;
|
||||||
|
String yrw801Path;
|
||||||
|
String tg100Path;
|
||||||
|
String mu5Path;
|
||||||
int mainFont;
|
int mainFont;
|
||||||
int patFont;
|
int patFont;
|
||||||
int audioRate;
|
int audioRate;
|
||||||
|
@ -910,6 +916,9 @@ class FurnaceGUI {
|
||||||
saaCore(1),
|
saaCore(1),
|
||||||
nesCore(0),
|
nesCore(0),
|
||||||
fdsCore(0),
|
fdsCore(0),
|
||||||
|
yrw801Path(""),
|
||||||
|
tg100Path(""),
|
||||||
|
mu5Path(""),
|
||||||
mainFont(0),
|
mainFont(0),
|
||||||
patFont(0),
|
patFont(0),
|
||||||
audioRate(44100),
|
audioRate(44100),
|
||||||
|
|
|
@ -883,6 +883,33 @@ void FurnaceGUI::drawSettings() {
|
||||||
ImGui::Text("FDS core");
|
ImGui::Text("FDS core");
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
ImGui::Combo("##FDSCore",&settings.fdsCore,nesCores,2);
|
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::EndChild();
|
||||||
ImGui::EndTabItem();
|
ImGui::EndTabItem();
|
||||||
|
@ -1789,6 +1816,9 @@ void FurnaceGUI::syncSettings() {
|
||||||
settings.saaCore=e->getConfInt("saaCore",1);
|
settings.saaCore=e->getConfInt("saaCore",1);
|
||||||
settings.nesCore=e->getConfInt("nesCore",0);
|
settings.nesCore=e->getConfInt("nesCore",0);
|
||||||
settings.fdsCore=e->getConfInt("fdsCore",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.mainFont=e->getConfInt("mainFont",0);
|
||||||
settings.patFont=e->getConfInt("patFont",0);
|
settings.patFont=e->getConfInt("patFont",0);
|
||||||
settings.mainFontPath=e->getConfString("mainFontPath","");
|
settings.mainFontPath=e->getConfString("mainFontPath","");
|
||||||
|
@ -1960,6 +1990,10 @@ void FurnaceGUI::syncSettings() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void FurnaceGUI::commitSettings() {
|
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("mainFontSize",settings.mainFontSize);
|
||||||
e->setConf("patFontSize",settings.patFontSize);
|
e->setConf("patFontSize",settings.patFontSize);
|
||||||
e->setConf("iconSize",settings.iconSize);
|
e->setConf("iconSize",settings.iconSize);
|
||||||
|
@ -1975,6 +2009,9 @@ void FurnaceGUI::commitSettings() {
|
||||||
e->setConf("saaCore",settings.saaCore);
|
e->setConf("saaCore",settings.saaCore);
|
||||||
e->setConf("nesCore",settings.nesCore);
|
e->setConf("nesCore",settings.nesCore);
|
||||||
e->setConf("fdsCore",settings.fdsCore);
|
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("mainFont",settings.mainFont);
|
||||||
e->setConf("patFont",settings.patFont);
|
e->setConf("patFont",settings.patFont);
|
||||||
e->setConf("mainFontPath",settings.mainFontPath);
|
e->setConf("mainFontPath",settings.mainFontPath);
|
||||||
|
@ -2063,6 +2100,12 @@ void FurnaceGUI::commitSettings() {
|
||||||
|
|
||||||
e->saveConf();
|
e->saveConf();
|
||||||
|
|
||||||
|
if (sampleRomsChanged) {
|
||||||
|
if (e->loadSampleRoms()) {
|
||||||
|
showError(e->getLastError());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!e->switchMaster()) {
|
if (!e->switchMaster()) {
|
||||||
showError("could not initialize audio!");
|
showError("could not initialize audio!");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue