parent
63ee7cf5d8
commit
e1b7618348
|
@ -127,8 +127,9 @@ void DivPlatformVB::updateWave(int ch) {
|
||||||
if (ch>=5) return;
|
if (ch>=5) return;
|
||||||
|
|
||||||
for (int i=0; i<32; i++) {
|
for (int i=0; i<32; i++) {
|
||||||
rWrite((ch<<7)+(i<<2),chan[ch].ws.output[i]);
|
rWrite((ch<<7)+(i<<2),chan[ch].ws.output[(i+chan[ch].antiClickWavePos)&31]);
|
||||||
}
|
}
|
||||||
|
chan[ch].antiClickWavePos&=31;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DivPlatformVB::writeEnv(int ch, bool upperByteToo) {
|
void DivPlatformVB::writeEnv(int ch, bool upperByteToo) {
|
||||||
|
@ -139,7 +140,17 @@ void DivPlatformVB::writeEnv(int ch, bool upperByteToo) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DivPlatformVB::tick(bool sysTick) {
|
void DivPlatformVB::tick(bool sysTick) {
|
||||||
|
bool mustUpdateWaves=false;
|
||||||
|
|
||||||
for (int i=0; i<6; i++) {
|
for (int i=0; i<6; i++) {
|
||||||
|
// anti-click
|
||||||
|
int actualFreq=2047-chan[i].freq;
|
||||||
|
if (antiClickEnabled && !screwThis && sysTick && actualFreq>0) {
|
||||||
|
chan[i].antiClickPeriodCount+=(chipClock/MAX(parent->getCurHz(),1.0f));
|
||||||
|
chan[i].antiClickWavePos+=chan[i].antiClickPeriodCount/actualFreq;
|
||||||
|
chan[i].antiClickPeriodCount%=actualFreq;
|
||||||
|
}
|
||||||
|
|
||||||
chan[i].std.next();
|
chan[i].std.next();
|
||||||
if (chan[i].std.vol.had) {
|
if (chan[i].std.vol.had) {
|
||||||
chan[i].outVol=VOL_SCALE_LINEAR(chan[i].vol&15,MIN(15,chan[i].std.vol.val),15);
|
chan[i].outVol=VOL_SCALE_LINEAR(chan[i].vol&15,MIN(15,chan[i].std.vol.val),15);
|
||||||
|
@ -192,10 +203,16 @@ void DivPlatformVB::tick(bool sysTick) {
|
||||||
}
|
}
|
||||||
if (chan[i].std.phaseReset.had && chan[i].std.phaseReset.val==1) {
|
if (chan[i].std.phaseReset.had && chan[i].std.phaseReset.val==1) {
|
||||||
chWrite(i,0x00,0x80);
|
chWrite(i,0x00,0x80);
|
||||||
|
chan[i].intWritten=true;
|
||||||
|
chan[i].antiClickWavePos=0;
|
||||||
|
chan[i].antiClickPeriodCount=0;
|
||||||
}
|
}
|
||||||
if (chan[i].active) {
|
if (chan[i].active) {
|
||||||
if (chan[i].ws.tick() || (chan[i].std.phaseReset.had && chan[i].std.phaseReset.val==1)) {
|
if (chan[i].ws.tick() || (chan[i].std.phaseReset.had && chan[i].std.phaseReset.val==1)) {
|
||||||
updateWave(i);
|
if (!romMode) {
|
||||||
|
chan[i].deferredWaveUpdate=true;
|
||||||
|
}
|
||||||
|
mustUpdateWaves=true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
||||||
|
@ -215,6 +232,32 @@ void DivPlatformVB::tick(bool sysTick) {
|
||||||
chan[i].freqChanged=false;
|
chan[i].freqChanged=false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// trigger wave changes
|
||||||
|
if (mustUpdateWaves && !romMode) {
|
||||||
|
//rWrite(0x580,1);
|
||||||
|
if (!screwThis) {
|
||||||
|
chWrite(0,0x00,0x00);
|
||||||
|
chWrite(1,0x00,0x00);
|
||||||
|
chWrite(2,0x00,0x00);
|
||||||
|
chWrite(3,0x00,0x00);
|
||||||
|
chWrite(4,0x00,0x00);
|
||||||
|
}
|
||||||
|
for (int i=0; i<5; i++) {
|
||||||
|
//if (chan[i].deferredWaveUpdate) {
|
||||||
|
//chan[i].deferredWaveUpdate=false;
|
||||||
|
updateWave(i);
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
if (!screwThis) {
|
||||||
|
// restore channel state...
|
||||||
|
for (int i=0; i<5; i++) {
|
||||||
|
if (chan[i].intWritten) {
|
||||||
|
chWrite(i,0x00,0x80);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int DivPlatformVB::dispatch(DivCommand c) {
|
int DivPlatformVB::dispatch(DivCommand c) {
|
||||||
|
@ -477,6 +520,7 @@ void DivPlatformVB::reset() {
|
||||||
for (int i=0; i<6; i++) {
|
for (int i=0; i<6; i++) {
|
||||||
chWrite(i,0x01,isMuted[i]?0:chan[i].pan);
|
chWrite(i,0x01,isMuted[i]?0:chan[i].pan);
|
||||||
chWrite(i,0x05,0x00);
|
chWrite(i,0x05,0x00);
|
||||||
|
chan[i].intWritten=true;
|
||||||
chWrite(i,0x00,0x80);
|
chWrite(i,0x00,0x80);
|
||||||
if (romMode) {
|
if (romMode) {
|
||||||
chWrite(i,0x06,0);
|
chWrite(i,0x06,0);
|
||||||
|
@ -545,6 +589,8 @@ void DivPlatformVB::setFlags(const DivConfig& flags) {
|
||||||
}
|
}
|
||||||
|
|
||||||
romMode=flags.getBool("romMode",false);
|
romMode=flags.getBool("romMode",false);
|
||||||
|
antiClickEnabled=!flags.getBool("noAntiClick",false);
|
||||||
|
screwThis=flags.getBool("screwThis",false);
|
||||||
|
|
||||||
if (vb!=NULL) {
|
if (vb!=NULL) {
|
||||||
delete vb;
|
delete vb;
|
||||||
|
|
|
@ -27,22 +27,27 @@
|
||||||
|
|
||||||
class DivPlatformVB: public DivDispatch {
|
class DivPlatformVB: public DivDispatch {
|
||||||
struct Channel: public SharedChannel<signed char> {
|
struct Channel: public SharedChannel<signed char> {
|
||||||
|
int antiClickPeriodCount, antiClickWavePos;
|
||||||
unsigned char pan, envLow, envHigh;
|
unsigned char pan, envLow, envHigh;
|
||||||
bool noise, deferredWaveUpdate;
|
bool noise, deferredWaveUpdate, intWritten;
|
||||||
signed short wave;
|
signed short wave;
|
||||||
DivWaveSynth ws;
|
DivWaveSynth ws;
|
||||||
Channel():
|
Channel():
|
||||||
SharedChannel<signed char>(15),
|
SharedChannel<signed char>(15),
|
||||||
|
antiClickPeriodCount(0),
|
||||||
|
antiClickWavePos(0),
|
||||||
pan(255),
|
pan(255),
|
||||||
envLow(0),
|
envLow(0),
|
||||||
envHigh(0),
|
envHigh(0),
|
||||||
noise(false),
|
noise(false),
|
||||||
deferredWaveUpdate(false),
|
deferredWaveUpdate(false),
|
||||||
|
intWritten(false),
|
||||||
wave(-1) {}
|
wave(-1) {}
|
||||||
};
|
};
|
||||||
Channel chan[6];
|
Channel chan[6];
|
||||||
DivDispatchOscBuffer* oscBuf[6];
|
DivDispatchOscBuffer* oscBuf[6];
|
||||||
bool isMuted[6];
|
bool isMuted[6];
|
||||||
|
bool antiClickEnabled, screwThis;
|
||||||
struct QueuedWrite {
|
struct QueuedWrite {
|
||||||
unsigned short addr;
|
unsigned short addr;
|
||||||
unsigned char val;
|
unsigned char val;
|
||||||
|
|
|
@ -2475,6 +2475,8 @@ bool FurnaceGUI::drawSysConf(int chan, int sysPos, DivSystem type, DivConfig& fl
|
||||||
}
|
}
|
||||||
case DIV_SYSTEM_VBOY: {
|
case DIV_SYSTEM_VBOY: {
|
||||||
bool romMode=flags.getBool("romMode",false);
|
bool romMode=flags.getBool("romMode",false);
|
||||||
|
bool noAntiClick=flags.getBool("noAntiClick",false);
|
||||||
|
bool screwThis=flags.getBool("screwThis",false);
|
||||||
|
|
||||||
ImGui::Text(_("Waveform storage mode:"));
|
ImGui::Text(_("Waveform storage mode:"));
|
||||||
ImGui::Indent();
|
ImGui::Indent();
|
||||||
|
@ -2488,9 +2490,23 @@ bool FurnaceGUI::drawSysConf(int chan, int sysPos, DivSystem type, DivConfig& fl
|
||||||
}
|
}
|
||||||
ImGui::Unindent();
|
ImGui::Unindent();
|
||||||
|
|
||||||
|
if (!romMode) {
|
||||||
|
if (ImGui::Checkbox(_("Disable anti-phase-reset"),&noAntiClick)) {
|
||||||
|
altered=true;
|
||||||
|
}
|
||||||
|
if (ImGui::Checkbox(_("I don't care about hardware"),&screwThis)) {
|
||||||
|
altered=true;
|
||||||
|
}
|
||||||
|
if (ImGui::IsItemHovered()) {
|
||||||
|
ImGui::SetTooltip(_("Virtual Boy hardware requires all channels to be disabled before writing to wave memory.\nif the clicks that arise from this annoy you, use this option.\nnote that your song won't play on hardware if you do so!"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (altered) {
|
if (altered) {
|
||||||
e->lockSave([&]() {
|
e->lockSave([&]() {
|
||||||
flags.set("romMode",romMode);
|
flags.set("romMode",romMode);
|
||||||
|
flags.set("noAntiClick",noAntiClick);
|
||||||
|
flags.set("screwThis",screwThis);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue