Merge branch 'tildearrow:master' into SID3
This commit is contained in:
commit
5fd93596b6
24 changed files with 472 additions and 302 deletions
|
|
@ -639,6 +639,8 @@ bool DivEngine::loadIT(unsigned char* file, size_t len) {
|
|||
logD("seek not needed...");
|
||||
}
|
||||
|
||||
logV("reading sample data (%d)",s->samples);
|
||||
|
||||
if (flags&8) { // compressed sample
|
||||
unsigned int ret=0;
|
||||
logV("decompression begin... (%d)",s->samples);
|
||||
|
|
@ -672,62 +674,66 @@ bool DivEngine::loadIT(unsigned char* file, size_t len) {
|
|||
}
|
||||
logV("got: %d",ret);
|
||||
} else {
|
||||
if (s->depth==DIV_SAMPLE_DEPTH_16BIT) {
|
||||
if (flags&4) { // downmix stereo
|
||||
for (unsigned int i=0; i<s->samples; i++) {
|
||||
short l;
|
||||
if (convert&2) {
|
||||
l=reader.readS_BE();
|
||||
} else {
|
||||
l=reader.readS();
|
||||
try {
|
||||
if (s->depth==DIV_SAMPLE_DEPTH_16BIT) {
|
||||
if (flags&4) { // downmix stereo
|
||||
for (unsigned int i=0; i<s->samples; i++) {
|
||||
short l;
|
||||
if (convert&2) {
|
||||
l=reader.readS_BE();
|
||||
} else {
|
||||
l=reader.readS();
|
||||
}
|
||||
if (!(convert&1)) {
|
||||
l^=0x8000;
|
||||
}
|
||||
s->data16[i]=l;
|
||||
}
|
||||
if (!(convert&1)) {
|
||||
l^=0x8000;
|
||||
for (unsigned int i=0; i<s->samples; i++) {
|
||||
short r;
|
||||
if (convert&2) {
|
||||
r=reader.readS_BE();
|
||||
} else {
|
||||
r=reader.readS();
|
||||
}
|
||||
if (!(convert&1)) {
|
||||
r^=0x8000;
|
||||
}
|
||||
s->data16[i]=(s->data16[i]+r)>>1;
|
||||
}
|
||||
s->data16[i]=l;
|
||||
}
|
||||
for (unsigned int i=0; i<s->samples; i++) {
|
||||
short r;
|
||||
if (convert&2) {
|
||||
r=reader.readS_BE();
|
||||
} else {
|
||||
r=reader.readS();
|
||||
} else {
|
||||
for (unsigned int i=0; i<s->samples; i++) {
|
||||
if (convert&2) {
|
||||
s->data16[i]=reader.readS_BE()^((convert&1)?0:0x8000);
|
||||
} else {
|
||||
s->data16[i]=reader.readS()^((convert&1)?0:0x8000);
|
||||
}
|
||||
}
|
||||
if (!(convert&1)) {
|
||||
r^=0x8000;
|
||||
}
|
||||
s->data16[i]=(s->data16[i]+r)>>1;
|
||||
}
|
||||
} else {
|
||||
for (unsigned int i=0; i<s->samples; i++) {
|
||||
if (convert&2) {
|
||||
s->data16[i]=reader.readS_BE()^((convert&1)?0:0x8000);
|
||||
} else {
|
||||
s->data16[i]=reader.readS()^((convert&1)?0:0x8000);
|
||||
if (flags&4) { // downmix stereo
|
||||
for (unsigned int i=0; i<s->samples; i++) {
|
||||
signed char l=reader.readC();
|
||||
if (!(convert&1)) {
|
||||
l^=0x80;
|
||||
}
|
||||
s->data8[i]=l;
|
||||
}
|
||||
for (unsigned int i=0; i<s->samples; i++) {
|
||||
signed char r=reader.readC();
|
||||
if (!(convert&1)) {
|
||||
r^=0x80;
|
||||
}
|
||||
s->data8[i]=(s->data8[i]+r)>>1;
|
||||
}
|
||||
} else {
|
||||
for (unsigned int i=0; i<s->samples; i++) {
|
||||
s->data8[i]=reader.readC()^((convert&1)?0:0x80);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (flags&4) { // downmix stereo
|
||||
for (unsigned int i=0; i<s->samples; i++) {
|
||||
signed char l=reader.readC();
|
||||
if (!(convert&1)) {
|
||||
l^=0x80;
|
||||
}
|
||||
s->data8[i]=l;
|
||||
}
|
||||
for (unsigned int i=0; i<s->samples; i++) {
|
||||
signed char r=reader.readC();
|
||||
if (!(convert&1)) {
|
||||
r^=0x80;
|
||||
}
|
||||
s->data8[i]=(s->data8[i]+r)>>1;
|
||||
}
|
||||
} else {
|
||||
for (unsigned int i=0; i<s->samples; i++) {
|
||||
s->data8[i]=reader.readC()^((convert&1)?0:0x80);
|
||||
}
|
||||
}
|
||||
} catch (EndOfFileException& e) {
|
||||
logW("premature end of file...");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ static void readSbiOpData(sbi_t& sbi, SafeReader& reader) {
|
|||
bool DivEngine::loadS3M(unsigned char* file, size_t len) {
|
||||
struct InvalidHeaderException {};
|
||||
bool success=false;
|
||||
bool opl2=!getConfInt("s3mOPL3",0);
|
||||
char magic[4]={0,0,0,0};
|
||||
SafeReader reader=SafeReader(file,len);
|
||||
warnings="";
|
||||
|
|
@ -273,11 +274,16 @@ bool DivEngine::loadS3M(unsigned char* file, size_t len) {
|
|||
bool hasPCM=false;
|
||||
bool hasFM=false;
|
||||
int numChans=0;
|
||||
int realNumChans=0;
|
||||
|
||||
for (int i=0; i<32; i++) {
|
||||
if (chanSettings[i]==255) continue;
|
||||
if ((chanSettings[i]&127)>=32) continue;
|
||||
if ((chanSettings[i]&127)>=16) {
|
||||
for (int ch=0; ch<32; ch++) {
|
||||
if (chanSettings[ch]!=255) realNumChans++;
|
||||
}
|
||||
|
||||
for (int ch=0; ch<32; ch++) {
|
||||
if (chanSettings[ch]==255) continue;
|
||||
if ((chanSettings[ch]&127)>=32) continue;
|
||||
if ((chanSettings[ch]&127)>=16) {
|
||||
hasFM=true;
|
||||
} else {
|
||||
hasPCM=true;
|
||||
|
|
@ -287,34 +293,69 @@ bool DivEngine::loadS3M(unsigned char* file, size_t len) {
|
|||
if (hasFM && hasPCM) break;
|
||||
}
|
||||
|
||||
int pcmChan=hasFM?9:0;
|
||||
int pcmChan=hasFM?(opl2 ? 9 : 18):0;
|
||||
int fmChan=hasPCM?32:0;
|
||||
int invalidChan=40;
|
||||
|
||||
for (int i=0; i<32; i++) {
|
||||
if (chanSettings[i]==255) {
|
||||
chanMap[i]=invalidChan++;
|
||||
for (int ch=0; ch<32; ch++) {
|
||||
if (chanSettings[ch]==255) {
|
||||
chanMap[ch]=invalidChan++;
|
||||
continue;
|
||||
}
|
||||
if ((chanSettings[i]&127)>=32) {
|
||||
chanMap[i]=invalidChan++;
|
||||
if ((chanSettings[ch]&127)>=32) {
|
||||
chanMap[ch]=invalidChan++;
|
||||
continue;
|
||||
}
|
||||
if ((chanSettings[i]&127)>=16) {
|
||||
chanMap[i]=fmChan++;
|
||||
if ((chanSettings[ch]&127)>=16) {
|
||||
chanMap[ch]=fmChan++;
|
||||
} else {
|
||||
chanMap[i]=pcmChan++;
|
||||
chanMap[ch]=pcmChan++;
|
||||
}
|
||||
}
|
||||
|
||||
char buffer[40];
|
||||
int chanIndex = 1;
|
||||
|
||||
if (hasPCM) {
|
||||
for (int i=pcmChan; i<32; i++) {
|
||||
ds.subsong[0]->chanShow[i]=false;
|
||||
ds.subsong[0]->chanShowChanOsc[i]=false;
|
||||
for(int ch = 0; ch < pcmChan - (realNumChans - (hasFM ? 9 : 0)); ch++)
|
||||
{
|
||||
ds.subsong[0]->chanShow[ch]=false;
|
||||
ds.subsong[0]->chanShowChanOsc[ch]=false;
|
||||
}
|
||||
|
||||
for (int ch=pcmChan; ch<32; ch++) {
|
||||
ds.subsong[0]->chanShow[ch]=false;
|
||||
ds.subsong[0]->chanShowChanOsc[ch]=false;
|
||||
}
|
||||
|
||||
for(int ch = 0; ch < 32; ch++)
|
||||
{
|
||||
if(ds.subsong[0]->chanShow[ch])
|
||||
{
|
||||
snprintf(buffer, 40, _("Channel %d"), chanIndex);
|
||||
ds.subsong[0]->chanName[ch] = buffer;
|
||||
chanIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hasFM && !opl2) {
|
||||
for (int ch=(hasPCM?32:0) + 9; ch<(hasPCM?32:0) + 18; ch++) {
|
||||
ds.subsong[0]->chanShow[ch]=false;
|
||||
ds.subsong[0]->chanShowChanOsc[ch]=false;
|
||||
}
|
||||
|
||||
chanIndex = 1;
|
||||
|
||||
for (int ch=(hasPCM?32:0); ch<(hasPCM?32:0) + 9; ch++) {
|
||||
snprintf(buffer, 40, _("FM %d"), chanIndex);
|
||||
ds.subsong[0]->chanName[ch] = buffer;
|
||||
chanIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
logV("numChans: %d",numChans);
|
||||
logV("realNumChans: %d",realNumChans);
|
||||
|
||||
ds.systemName="PC";
|
||||
if (hasPCM) {
|
||||
|
|
@ -327,7 +368,7 @@ bool DivEngine::loadS3M(unsigned char* file, size_t len) {
|
|||
ds.systemLen++;
|
||||
}
|
||||
if (hasFM) {
|
||||
ds.system[ds.systemLen]=DIV_SYSTEM_OPL2;
|
||||
ds.system[ds.systemLen]=opl2 ? DIV_SYSTEM_OPL2 : DIV_SYSTEM_OPL3;
|
||||
ds.systemVol[ds.systemLen]=1.0f;
|
||||
ds.systemPan[ds.systemLen]=0;
|
||||
ds.systemLen++;
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@ static float oscDebugMax=1.0;
|
|||
static float oscDebugPower=1.0;
|
||||
static int oscDebugRepeat=1;
|
||||
static int numApples=1;
|
||||
static int getGainChan=0;
|
||||
static int getGainVol=0;
|
||||
|
||||
static void _drawOsc(const ImDrawList* drawList, const ImDrawCmd* cmd) {
|
||||
if (cmd!=NULL) {
|
||||
|
|
@ -721,6 +723,13 @@ void FurnaceGUI::drawDebug() {
|
|||
ImGui::TreePop();
|
||||
}
|
||||
#endif
|
||||
if (ImGui::TreeNode("Get Gain Test")) {
|
||||
float realVol=e->getGain(getGainChan,getGainVol);
|
||||
ImGui::InputInt("Chan",&getGainChan);
|
||||
ImGui::InputInt("Vol",&getGainVol);
|
||||
ImGui::Text("result: %.0f%%",realVol*100.0f);
|
||||
ImGui::TreePop();
|
||||
}
|
||||
if (ImGui::TreeNode("User Interface")) {
|
||||
if (ImGui::Button("Inspect")) {
|
||||
inspectorOpen=!inspectorOpen;
|
||||
|
|
|
|||
|
|
@ -676,6 +676,17 @@ void FurnaceGUI::doAction(int what) {
|
|||
latchTarget=0;
|
||||
latchNibble=false;
|
||||
break;
|
||||
case GUI_ACTION_PAT_ABSORB_INSTRUMENT: {
|
||||
DivPattern* pat=e->curPat[cursor.xCoarse].getPattern(e->curOrders->ord[cursor.xCoarse][curOrder],false);
|
||||
if (!pat) break;
|
||||
for (int i=cursor.y; i>=0; i--) {
|
||||
if (pat->data[i][2] >= 0) {
|
||||
curIns=pat->data[i][2];
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case GUI_ACTION_INS_LIST_ADD:
|
||||
if (settings.insTypeMenu) {
|
||||
|
|
|
|||
|
|
@ -817,6 +817,7 @@ enum FurnaceGUIActions {
|
|||
GUI_ACTION_PAT_LATCH,
|
||||
GUI_ACTION_PAT_SCROLL_MODE,
|
||||
GUI_ACTION_PAT_CLEAR_LATCH,
|
||||
GUI_ACTION_PAT_ABSORB_INSTRUMENT,
|
||||
GUI_ACTION_PAT_MAX,
|
||||
|
||||
GUI_ACTION_INS_LIST_MIN,
|
||||
|
|
@ -1958,6 +1959,7 @@ class FurnaceGUI {
|
|||
unsigned int maxUndoSteps;
|
||||
float vibrationStrength;
|
||||
int vibrationLength;
|
||||
int s3mOPL3;
|
||||
String mainFontPath;
|
||||
String headFontPath;
|
||||
String patFontPath;
|
||||
|
|
@ -2214,6 +2216,7 @@ class FurnaceGUI {
|
|||
maxUndoSteps(100),
|
||||
vibrationStrength(0.5f),
|
||||
vibrationLength(20),
|
||||
s3mOPL3(0),
|
||||
mainFontPath(""),
|
||||
headFontPath(""),
|
||||
patFontPath(""),
|
||||
|
|
|
|||
|
|
@ -688,6 +688,7 @@ const FurnaceGUIActionDef guiActions[GUI_ACTION_MAX]={
|
|||
D("PAT_LATCH", _N("Set note input latch"), 0),
|
||||
D("PAT_SCROLL_MODE", _N("Change mobile scroll mode"), 0),
|
||||
D("PAT_CLEAR_LATCH", _N("Clear note input latch"), 0),
|
||||
D("PAT_ABSORB_INSTRUMENT", _N("Set current instrument to channel's current instrument column"), 0),
|
||||
D("PAT_MAX", "", NOT_AN_ACTION),
|
||||
|
||||
D("INS_LIST_MIN", _N("---Instrument list"), NOT_AN_ACTION),
|
||||
|
|
|
|||
|
|
@ -1254,6 +1254,14 @@ void FurnaceGUI::drawSettings() {
|
|||
}
|
||||
popDestColor();
|
||||
|
||||
// SUBSECTION IMPORT
|
||||
CONFIG_SUBSECTION(_("Import"));
|
||||
bool s3mOPL3B=settings.s3mOPL3;
|
||||
if (ImGui::Checkbox(_("Use OPL3 instead of OPL2 for S3M import"),&s3mOPL3B)) {
|
||||
settings.s3mOPL3=s3mOPL3B;
|
||||
settingsChanged=true;
|
||||
}
|
||||
|
||||
END_SECTION;
|
||||
}
|
||||
CONFIG_SECTION(_("Audio")) {
|
||||
|
|
@ -2415,6 +2423,7 @@ void FurnaceGUI::drawSettings() {
|
|||
UI_KEYBIND_CONFIG(GUI_ACTION_PAT_EXPAND_SONG);
|
||||
UI_KEYBIND_CONFIG(GUI_ACTION_PAT_LATCH);
|
||||
UI_KEYBIND_CONFIG(GUI_ACTION_PAT_CLEAR_LATCH);
|
||||
UI_KEYBIND_CONFIG(GUI_ACTION_PAT_ABSORB_INSTRUMENT);
|
||||
|
||||
KEYBIND_CONFIG_END;
|
||||
ImGui::TreePop();
|
||||
|
|
@ -4746,6 +4755,8 @@ void FurnaceGUI::readConfig(DivConfig& conf, FurnaceGUISettingGroups groups) {
|
|||
settings.vibrationStrength=conf.getFloat("vibrationStrength",0.5f);
|
||||
settings.vibrationLength=conf.getInt("vibrationLength",20);
|
||||
|
||||
settings.s3mOPL3=conf.getInt("s3mOPL3",0);
|
||||
|
||||
settings.backupEnable=conf.getInt("backupEnable",1);
|
||||
settings.backupInterval=conf.getInt("backupInterval",30);
|
||||
settings.backupMaxCopies=conf.getInt("backupMaxCopies",5);
|
||||
|
|
@ -5258,6 +5269,7 @@ void FurnaceGUI::readConfig(DivConfig& conf, FurnaceGUISettingGroups groups) {
|
|||
clampSetting(settings.backupMaxCopies,1,100);
|
||||
clampSetting(settings.autoFillSave,0,1);
|
||||
clampSetting(settings.autoMacroStepSize,0,1);
|
||||
clampSetting(settings.s3mOPL3,0,1);
|
||||
|
||||
if (settings.exportLoops<0.0) settings.exportLoops=0.0;
|
||||
if (settings.exportFadeOut<0.0) settings.exportFadeOut=0.0;
|
||||
|
|
@ -5331,6 +5343,8 @@ void FurnaceGUI::writeConfig(DivConfig& conf, FurnaceGUISettingGroups groups) {
|
|||
conf.set("vibrationStrength",settings.vibrationStrength);
|
||||
conf.set("vibrationLength",settings.vibrationLength);
|
||||
|
||||
conf.set("s3mOPL3",settings.s3mOPL3);
|
||||
|
||||
conf.set("backupEnable",settings.backupEnable);
|
||||
conf.set("backupInterval",settings.backupInterval);
|
||||
conf.set("backupMaxCopies",settings.backupMaxCopies);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue