C64: use full cutoff/duty range
this means .dmf becomes a second-class citizen since it only supports a range of 0-100 (yeah) for arbitrary reasons... the last bit to do is add effect that allows you to use the full range
This commit is contained in:
parent
4bbfc22c2a
commit
9b6db75d4f
|
@ -691,7 +691,7 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
||||||
ins->c64.s=reader.readC();
|
ins->c64.s=reader.readC();
|
||||||
ins->c64.r=reader.readC();
|
ins->c64.r=reader.readC();
|
||||||
|
|
||||||
ins->c64.duty=reader.readC();
|
ins->c64.duty=(reader.readC()*4095)/100;
|
||||||
|
|
||||||
ins->c64.ringMod=reader.readC();
|
ins->c64.ringMod=reader.readC();
|
||||||
ins->c64.oscSync=reader.readC();
|
ins->c64.oscSync=reader.readC();
|
||||||
|
@ -704,7 +704,7 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
||||||
ins->c64.initFilter=reader.readC();
|
ins->c64.initFilter=reader.readC();
|
||||||
|
|
||||||
ins->c64.res=reader.readC();
|
ins->c64.res=reader.readC();
|
||||||
ins->c64.cut=reader.readC();
|
ins->c64.cut=(reader.readC()*2047)/100;
|
||||||
ins->c64.hp=reader.readC();
|
ins->c64.hp=reader.readC();
|
||||||
ins->c64.bp=reader.readC();
|
ins->c64.bp=reader.readC();
|
||||||
ins->c64.lp=reader.readC();
|
ins->c64.lp=reader.readC();
|
||||||
|
@ -1534,7 +1534,7 @@ SafeWriter* DivEngine::saveFur() {
|
||||||
w->writeC(ins->c64.d);
|
w->writeC(ins->c64.d);
|
||||||
w->writeC(ins->c64.s);
|
w->writeC(ins->c64.s);
|
||||||
w->writeC(ins->c64.r);
|
w->writeC(ins->c64.r);
|
||||||
w->writeS((ins->c64.duty*4096)/100);
|
w->writeS(ins->c64.duty);
|
||||||
w->writeC(ins->c64.ringMod);
|
w->writeC(ins->c64.ringMod);
|
||||||
w->writeC(ins->c64.oscSync);
|
w->writeC(ins->c64.oscSync);
|
||||||
w->writeC(ins->c64.toFilter);
|
w->writeC(ins->c64.toFilter);
|
||||||
|
@ -1545,7 +1545,7 @@ SafeWriter* DivEngine::saveFur() {
|
||||||
w->writeC(ins->c64.bp);
|
w->writeC(ins->c64.bp);
|
||||||
w->writeC(ins->c64.hp);
|
w->writeC(ins->c64.hp);
|
||||||
w->writeC(ins->c64.ch3off);
|
w->writeC(ins->c64.ch3off);
|
||||||
w->writeS((ins->c64.cut*2047)/100);
|
w->writeS(ins->c64.cut);
|
||||||
w->writeC(ins->c64.dutyIsAbs);
|
w->writeC(ins->c64.dutyIsAbs);
|
||||||
w->writeC(ins->c64.filterIsAbs);
|
w->writeC(ins->c64.filterIsAbs);
|
||||||
|
|
||||||
|
@ -1783,7 +1783,8 @@ SafeWriter* DivEngine::saveDMF() {
|
||||||
w->writeC(i->c64.s);
|
w->writeC(i->c64.s);
|
||||||
w->writeC(i->c64.r);
|
w->writeC(i->c64.r);
|
||||||
|
|
||||||
w->writeC(i->c64.duty);
|
logW("duty and cutoff precision will be lost!\n");
|
||||||
|
w->writeC((i->c64.duty*100)/4095);
|
||||||
|
|
||||||
w->writeC(i->c64.ringMod);
|
w->writeC(i->c64.ringMod);
|
||||||
w->writeC(i->c64.oscSync);
|
w->writeC(i->c64.oscSync);
|
||||||
|
@ -1793,7 +1794,7 @@ SafeWriter* DivEngine::saveDMF() {
|
||||||
w->writeC(i->c64.initFilter);
|
w->writeC(i->c64.initFilter);
|
||||||
|
|
||||||
w->writeC(i->c64.res);
|
w->writeC(i->c64.res);
|
||||||
w->writeC(i->c64.cut);
|
w->writeC((i->c64.cut*100)/2047);
|
||||||
w->writeC(i->c64.hp);
|
w->writeC(i->c64.hp);
|
||||||
w->writeC(i->c64.bp);
|
w->writeC(i->c64.bp);
|
||||||
w->writeC(i->c64.lp);
|
w->writeC(i->c64.lp);
|
||||||
|
|
|
@ -116,10 +116,11 @@ struct DivInstrumentGB {
|
||||||
struct DivInstrumentC64 {
|
struct DivInstrumentC64 {
|
||||||
bool triOn, sawOn, pulseOn, noiseOn;
|
bool triOn, sawOn, pulseOn, noiseOn;
|
||||||
unsigned char a, d, s, r;
|
unsigned char a, d, s, r;
|
||||||
unsigned char duty;
|
unsigned short duty;
|
||||||
unsigned char ringMod, oscSync;
|
unsigned char ringMod, oscSync;
|
||||||
bool toFilter, volIsCutoff, initFilter, dutyIsAbs, filterIsAbs;
|
bool toFilter, volIsCutoff, initFilter, dutyIsAbs, filterIsAbs;
|
||||||
unsigned char res, cut;
|
unsigned char res;
|
||||||
|
unsigned short cut;
|
||||||
bool hp, lp, bp, ch3off;
|
bool hp, lp, bp, ch3off;
|
||||||
|
|
||||||
DivInstrumentC64():
|
DivInstrumentC64():
|
||||||
|
@ -131,7 +132,7 @@ struct DivInstrumentC64 {
|
||||||
d(8),
|
d(8),
|
||||||
s(0),
|
s(0),
|
||||||
r(0),
|
r(0),
|
||||||
duty(50),
|
duty(2048),
|
||||||
ringMod(0),
|
ringMod(0),
|
||||||
oscSync(0),
|
oscSync(0),
|
||||||
toFilter(false),
|
toFilter(false),
|
||||||
|
|
|
@ -100,7 +100,7 @@ int DivPlatformC64::dispatch(DivCommand c) {
|
||||||
chan[c.chan].active=true;
|
chan[c.chan].active=true;
|
||||||
chan[c.chan].keyOn=true;
|
chan[c.chan].keyOn=true;
|
||||||
if (chan[c.chan].insChanged || chan[c.chan].resetDuty || ins->std.waveMacroLen>0) {
|
if (chan[c.chan].insChanged || chan[c.chan].resetDuty || ins->std.waveMacroLen>0) {
|
||||||
chan[c.chan].duty=(ins->c64.duty*4095)/100;
|
chan[c.chan].duty=ins->c64.duty;
|
||||||
rWrite(c.chan*7+2,chan[c.chan].duty&0xff);
|
rWrite(c.chan*7+2,chan[c.chan].duty&0xff);
|
||||||
rWrite(c.chan*7+3,chan[c.chan].duty>>8);
|
rWrite(c.chan*7+3,chan[c.chan].duty>>8);
|
||||||
}
|
}
|
||||||
|
@ -116,7 +116,7 @@ int DivPlatformC64::dispatch(DivCommand c) {
|
||||||
if (chan[c.chan].insChanged || chan[c.chan].resetFilter) {
|
if (chan[c.chan].insChanged || chan[c.chan].resetFilter) {
|
||||||
chan[c.chan].filter=ins->c64.toFilter;
|
chan[c.chan].filter=ins->c64.toFilter;
|
||||||
if (ins->c64.initFilter) {
|
if (ins->c64.initFilter) {
|
||||||
filtCut=ins->c64.cut*2047/100;
|
filtCut=ins->c64.cut;
|
||||||
filtRes=ins->c64.res;
|
filtRes=ins->c64.res;
|
||||||
filtControl=ins->c64.lp|(ins->c64.bp<<1)|(ins->c64.hp<<2)|(ins->c64.ch3off<<3);
|
filtControl=ins->c64.lp|(ins->c64.bp<<1)|(ins->c64.hp<<2)|(ins->c64.ch3off<<3);
|
||||||
updateFilter();
|
updateFilter();
|
||||||
|
@ -229,7 +229,7 @@ int DivPlatformC64::dispatch(DivCommand c) {
|
||||||
case DIV_CMD_C64_FILTER_RESET:
|
case DIV_CMD_C64_FILTER_RESET:
|
||||||
if (c.value&15) {
|
if (c.value&15) {
|
||||||
DivInstrument* ins=parent->getIns(chan[c.chan].ins);
|
DivInstrument* ins=parent->getIns(chan[c.chan].ins);
|
||||||
filtCut=ins->c64.cut*2047/100;
|
filtCut=ins->c64.cut;
|
||||||
updateFilter();
|
updateFilter();
|
||||||
}
|
}
|
||||||
chan[c.chan].resetFilter=c.value>>4;
|
chan[c.chan].resetFilter=c.value>>4;
|
||||||
|
@ -237,7 +237,7 @@ int DivPlatformC64::dispatch(DivCommand c) {
|
||||||
case DIV_CMD_C64_DUTY_RESET:
|
case DIV_CMD_C64_DUTY_RESET:
|
||||||
if (c.value&15) {
|
if (c.value&15) {
|
||||||
DivInstrument* ins=parent->getIns(chan[c.chan].ins);
|
DivInstrument* ins=parent->getIns(chan[c.chan].ins);
|
||||||
chan[c.chan].duty=(ins->c64.duty*4095)/100;
|
chan[c.chan].duty=ins->c64.duty;
|
||||||
rWrite(c.chan*7+2,chan[c.chan].duty&0xff);
|
rWrite(c.chan*7+2,chan[c.chan].duty&0xff);
|
||||||
rWrite(c.chan*7+3,chan[c.chan].duty>>8);
|
rWrite(c.chan*7+3,chan[c.chan].duty>>8);
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,8 @@ const int _THIRTY_ONE=31;
|
||||||
const int _SIXTY_FOUR=64;
|
const int _SIXTY_FOUR=64;
|
||||||
const int _ONE_HUNDRED=100;
|
const int _ONE_HUNDRED=100;
|
||||||
const int _ONE_HUNDRED_TWENTY_SEVEN=127;
|
const int _ONE_HUNDRED_TWENTY_SEVEN=127;
|
||||||
|
const int _TWO_THOUSAND_FORTY_SEVEN=2047;
|
||||||
|
const int _FOUR_THOUSAND_NINETY_FIVE=4095;
|
||||||
|
|
||||||
const FurnaceGUIColors fxColors[16]={
|
const FurnaceGUIColors fxColors[16]={
|
||||||
GUI_COLOR_PATTERN_EFFECT_MISC, // 00
|
GUI_COLOR_PATTERN_EFFECT_MISC, // 00
|
||||||
|
@ -666,7 +668,7 @@ void FurnaceGUI::drawInsEdit() {
|
||||||
ImGui::SliderScalar("Decay",ImGuiDataType_U8,&ins->c64.d,&_ZERO,&_FIFTEEN);
|
ImGui::SliderScalar("Decay",ImGuiDataType_U8,&ins->c64.d,&_ZERO,&_FIFTEEN);
|
||||||
ImGui::SliderScalar("Sustain",ImGuiDataType_U8,&ins->c64.s,&_ZERO,&_FIFTEEN);
|
ImGui::SliderScalar("Sustain",ImGuiDataType_U8,&ins->c64.s,&_ZERO,&_FIFTEEN);
|
||||||
ImGui::SliderScalar("Release",ImGuiDataType_U8,&ins->c64.r,&_ZERO,&_FIFTEEN);
|
ImGui::SliderScalar("Release",ImGuiDataType_U8,&ins->c64.r,&_ZERO,&_FIFTEEN);
|
||||||
ImGui::SliderScalar("Duty",ImGuiDataType_U8,&ins->c64.duty,&_ZERO,&_ONE_HUNDRED);
|
ImGui::SliderScalar("Duty",ImGuiDataType_U16,&ins->c64.duty,&_ZERO,&_FOUR_THOUSAND_NINETY_FIVE);
|
||||||
|
|
||||||
bool ringMod=ins->c64.ringMod;
|
bool ringMod=ins->c64.ringMod;
|
||||||
if (ImGui::Checkbox("Ring Modulation",&ringMod)) ins->c64.ringMod=ringMod;
|
if (ImGui::Checkbox("Ring Modulation",&ringMod)) ins->c64.ringMod=ringMod;
|
||||||
|
@ -676,7 +678,7 @@ void FurnaceGUI::drawInsEdit() {
|
||||||
ImGui::Checkbox("Enable filter",&ins->c64.toFilter);
|
ImGui::Checkbox("Enable filter",&ins->c64.toFilter);
|
||||||
ImGui::Checkbox("Initialize filter",&ins->c64.initFilter);
|
ImGui::Checkbox("Initialize filter",&ins->c64.initFilter);
|
||||||
|
|
||||||
ImGui::SliderScalar("Cutoff",ImGuiDataType_U8,&ins->c64.cut,&_ZERO,&_ONE_HUNDRED);
|
ImGui::SliderScalar("Cutoff",ImGuiDataType_U16,&ins->c64.cut,&_ZERO,&_TWO_THOUSAND_FORTY_SEVEN);
|
||||||
ImGui::SliderScalar("Resonance",ImGuiDataType_U8,&ins->c64.res,&_ZERO,&_FIFTEEN);
|
ImGui::SliderScalar("Resonance",ImGuiDataType_U8,&ins->c64.res,&_ZERO,&_FIFTEEN);
|
||||||
|
|
||||||
ImGui::Text("Filter Mode");
|
ImGui::Text("Filter Mode");
|
||||||
|
|
Loading…
Reference in a new issue