mirror of
https://github.com/tildearrow/furnace.git
synced 2024-11-16 01:35:07 +00:00
More #79 - Add S3I Adlib instrument support. Also fix SafeReader SEEK_CUR
handling (wasn't used at all).
This commit is contained in:
parent
629049dea0
commit
cbe74b26ad
3 changed files with 87 additions and 4 deletions
|
@ -1223,6 +1223,7 @@ enum DivInsFormats {
|
||||||
DIV_INSFORMAT_VGI,
|
DIV_INSFORMAT_VGI,
|
||||||
DIV_INSFORMAT_FTI,
|
DIV_INSFORMAT_FTI,
|
||||||
DIV_INSFORMAT_BTI,
|
DIV_INSFORMAT_BTI,
|
||||||
|
DIV_INSFORMAT_S3I,
|
||||||
DIV_INSFORMAT_SBI,
|
DIV_INSFORMAT_SBI,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1343,6 +1344,8 @@ bool DivEngine::addInstrumentFromFile(const char* path) {
|
||||||
format=DIV_INSFORMAT_FTI;
|
format=DIV_INSFORMAT_FTI;
|
||||||
} else if (extS==String(".bti")) {
|
} else if (extS==String(".bti")) {
|
||||||
format=DIV_INSFORMAT_BTI;
|
format=DIV_INSFORMAT_BTI;
|
||||||
|
} else if (extS==String(".s3i")) {
|
||||||
|
format = DIV_INSFORMAT_S3I;
|
||||||
} else if (extS==String(".sbi")) {
|
} else if (extS==String(".sbi")) {
|
||||||
format = DIV_INSFORMAT_SBI;
|
format = DIV_INSFORMAT_SBI;
|
||||||
}
|
}
|
||||||
|
@ -1675,6 +1678,85 @@ bool DivEngine::addInstrumentFromFile(const char* path) {
|
||||||
break;
|
break;
|
||||||
case DIV_INSFORMAT_BTI:
|
case DIV_INSFORMAT_BTI:
|
||||||
break;
|
break;
|
||||||
|
case DIV_INSFORMAT_S3I:
|
||||||
|
try {
|
||||||
|
reader.seek(0, SEEK_SET);
|
||||||
|
|
||||||
|
uint8_t s3i_type = reader.readC();
|
||||||
|
|
||||||
|
if (s3i_type >= 2) {
|
||||||
|
ins->type = DIV_INS_OPL;
|
||||||
|
// skip internal filename - we'll use the long name description
|
||||||
|
reader.seek(12, SEEK_CUR);
|
||||||
|
|
||||||
|
// skip reserved bytes
|
||||||
|
reader.seek(3, SEEK_CUR);
|
||||||
|
|
||||||
|
// 12-byte opl value
|
||||||
|
uint8_t s3i_Mcharacteristics = reader.readC();
|
||||||
|
uint8_t s3i_Ccharacteristics = reader.readC();
|
||||||
|
uint8_t s3i_Mscaling_output = reader.readC();
|
||||||
|
uint8_t s3i_Cscaling_output = reader.readC();
|
||||||
|
uint8_t s3i_Meg_AD = reader.readC();
|
||||||
|
uint8_t s3i_Ceg_AD = reader.readC();
|
||||||
|
uint8_t s3i_Meg_SR = reader.readC();
|
||||||
|
uint8_t s3i_Ceg_SR = reader.readC();
|
||||||
|
uint8_t s3i_Mwave = reader.readC();
|
||||||
|
uint8_t s3i_Cwave = reader.readC();
|
||||||
|
uint8_t s3i_FeedConnect = reader.readC();
|
||||||
|
|
||||||
|
DivInstrumentFM::Operator& opM = ins->fm.op[0];
|
||||||
|
DivInstrumentFM::Operator& opC = ins->fm.op[1];
|
||||||
|
ins->fm.ops = 2;
|
||||||
|
opM.mult = s3i_Mcharacteristics & 0xF;
|
||||||
|
opM.ksr = ((s3i_Mcharacteristics >> 4) & 0x1);
|
||||||
|
opM.sus = ((s3i_Mcharacteristics >> 5) & 0x1);
|
||||||
|
opM.vib = ((s3i_Mcharacteristics >> 6) & 0x1);
|
||||||
|
opM.am = ((s3i_Mcharacteristics >> 7) & 0x1);
|
||||||
|
opM.tl = s3i_Mscaling_output & 0x3F;
|
||||||
|
opM.ksl = ((s3i_Mscaling_output >> 6) & 0x3);
|
||||||
|
opM.ar = ((s3i_Meg_AD >> 4) & 0xF);
|
||||||
|
opM.dr = (s3i_Meg_AD & 0xF);
|
||||||
|
opM.rr = (s3i_Meg_SR & 0xF);
|
||||||
|
opM.sl = ((s3i_Meg_SR >> 4) & 0xF);
|
||||||
|
opM.ws = s3i_Mwave;
|
||||||
|
|
||||||
|
ins->fm.alg = (s3i_FeedConnect & 0x1);
|
||||||
|
ins->fm.fb = ((s3i_FeedConnect >> 1) & 0x7);
|
||||||
|
|
||||||
|
opC.mult = s3i_Ccharacteristics & 0xF;
|
||||||
|
opC.ksr = ((s3i_Ccharacteristics >> 4) & 0x1);
|
||||||
|
opC.sus = ((s3i_Ccharacteristics >> 5) & 0x1);
|
||||||
|
opC.vib = ((s3i_Ccharacteristics >> 6) & 0x1);
|
||||||
|
opC.am = ((s3i_Ccharacteristics >> 7) & 0x1);
|
||||||
|
opC.tl = s3i_Cscaling_output & 0x3F;
|
||||||
|
opC.ksl = ((s3i_Cscaling_output >> 6) & 0x3);
|
||||||
|
opC.ar = ((s3i_Ceg_AD >> 4) & 0xF);
|
||||||
|
opC.dr = (s3i_Ceg_AD & 0xF);
|
||||||
|
opC.rr = (s3i_Ceg_SR & 0xF);
|
||||||
|
opC.sl = ((s3i_Ceg_SR >> 4) & 0xF);
|
||||||
|
opC.ws = s3i_Cwave;
|
||||||
|
|
||||||
|
// Skip more stuff we don't need
|
||||||
|
reader.seek(21, SEEK_CUR);
|
||||||
|
} else {
|
||||||
|
logE("S3I PCM samples currently not supported.");
|
||||||
|
}
|
||||||
|
ins->name = reader.readString(28);
|
||||||
|
int s3i_signature = reader.readI();
|
||||||
|
|
||||||
|
if (s3i_signature != 0x49524353) {
|
||||||
|
logW("S3I signature invalid.");
|
||||||
|
};
|
||||||
|
}
|
||||||
|
catch (EndOfFileException& e) {
|
||||||
|
lastError = "premature end of file";
|
||||||
|
logE("premature end of file!\n");
|
||||||
|
delete ins;
|
||||||
|
delete[] buf;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case DIV_INSFORMAT_SBI:
|
case DIV_INSFORMAT_SBI:
|
||||||
try {
|
try {
|
||||||
reader.seek(0, SEEK_SET);
|
reader.seek(0, SEEK_SET);
|
||||||
|
|
|
@ -30,14 +30,14 @@ bool SafeReader::seek(ssize_t where, int whence) {
|
||||||
curSeek=where;
|
curSeek=where;
|
||||||
break;
|
break;
|
||||||
case SEEK_CUR: {
|
case SEEK_CUR: {
|
||||||
ssize_t finalSeek=len+where;
|
ssize_t finalSeek=curSeek+where;
|
||||||
if (finalSeek<0) return false;
|
if (finalSeek<0) return false;
|
||||||
if (finalSeek>(ssize_t)len) return false;
|
if (finalSeek>(ssize_t)len) return false;
|
||||||
curSeek=finalSeek;
|
curSeek=finalSeek;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SEEK_END: {
|
case SEEK_END: {
|
||||||
ssize_t finalSeek=len-where;
|
ssize_t finalSeek=curSeek-where;
|
||||||
if (finalSeek<0) return false;
|
if (finalSeek<0) return false;
|
||||||
if (finalSeek>(ssize_t)len) return false;
|
if (finalSeek>(ssize_t)len) return false;
|
||||||
curSeek=finalSeek;
|
curSeek=finalSeek;
|
||||||
|
|
|
@ -4658,9 +4658,9 @@ void FurnaceGUI::openFileDialog(FurnaceGUIFileDialogs type) {
|
||||||
if (!dirExists(workingDirIns)) workingDirIns=getHomeDir();
|
if (!dirExists(workingDirIns)) workingDirIns=getHomeDir();
|
||||||
hasOpened=fileDialog->openLoad(
|
hasOpened=fileDialog->openLoad(
|
||||||
"Load Instrument",
|
"Load Instrument",
|
||||||
{"compatible files", "*.fui *.dmp *.tfi *.vgi, *.sbi",
|
{"compatible files", "*.fui *.dmp *.tfi *.vgi *.s3i *.sbi",
|
||||||
"all files", ".*"},
|
"all files", ".*"},
|
||||||
"compatible files{.fui,.dmp,.tfi,.vgi,.sbi},.*",
|
"compatible files{.fui,.dmp,.tfi,.vgi,.s3i,.sbi},.*",
|
||||||
workingDirIns,
|
workingDirIns,
|
||||||
dpiScale
|
dpiScale
|
||||||
);
|
);
|
||||||
|
@ -6886,6 +6886,7 @@ bool FurnaceGUI::init() {
|
||||||
|
|
||||||
ImGuiFileDialog::Instance()->SetFileStyle(IGFD_FileStyleByExtension,".tfi",ImVec4(1.0f,0.5f,0.5f,1.0f),ICON_FA_FILE);
|
ImGuiFileDialog::Instance()->SetFileStyle(IGFD_FileStyleByExtension,".tfi",ImVec4(1.0f,0.5f,0.5f,1.0f),ICON_FA_FILE);
|
||||||
ImGuiFileDialog::Instance()->SetFileStyle(IGFD_FileStyleByExtension,".vgi",ImVec4(1.0f,0.5f,0.5f,1.0f),ICON_FA_FILE);
|
ImGuiFileDialog::Instance()->SetFileStyle(IGFD_FileStyleByExtension,".vgi",ImVec4(1.0f,0.5f,0.5f,1.0f),ICON_FA_FILE);
|
||||||
|
ImGuiFileDialog::Instance()->SetFileStyle(IGFD_FileStyleByExtension,".s3i",ImVec4(1.0f,0.5f,0.5f,1.0f),ICON_FA_FILE);
|
||||||
ImGuiFileDialog::Instance()->SetFileStyle(IGFD_FileStyleByExtension,".sbi",ImVec4(1.0f,0.5f,0.5f,1.0f),ICON_FA_FILE);
|
ImGuiFileDialog::Instance()->SetFileStyle(IGFD_FileStyleByExtension,".sbi",ImVec4(1.0f,0.5f,0.5f,1.0f),ICON_FA_FILE);
|
||||||
ImGuiFileDialog::Instance()->SetFileStyle(IGFD_FileStyleByExtension,".fti",ImVec4(1.0f,0.5f,0.5f,1.0f),ICON_FA_FILE);
|
ImGuiFileDialog::Instance()->SetFileStyle(IGFD_FileStyleByExtension,".fti",ImVec4(1.0f,0.5f,0.5f,1.0f),ICON_FA_FILE);
|
||||||
ImGuiFileDialog::Instance()->SetFileStyle(IGFD_FileStyleByExtension,".bti",ImVec4(1.0f,0.5f,0.5f,1.0f),ICON_FA_FILE);
|
ImGuiFileDialog::Instance()->SetFileStyle(IGFD_FileStyleByExtension,".bti",ImVec4(1.0f,0.5f,0.5f,1.0f),ICON_FA_FILE);
|
||||||
|
|
Loading…
Reference in a new issue