I don't trust you

where did you get these numbers from? did you make them up?
first you go "bruh bruh bruh" on me and then you drop this. couldn't
you at least look around a bit?!

since when has OPZ been clocked at 4MHz? who said that it does?
the chip's been designed to run at NTSC colorburst frequency, damn it!

on top of that, you didn't have to make up anything. AT ALL.
fixed frequency is simpler than eating with a fork. you just write the
frequency IN HERTZ (!!), the block and that's it.
really? were these numbers necessary?

oh man....
This commit is contained in:
tildearrow 2024-09-22 16:56:54 -05:00
parent 838646800a
commit 1f1b9fcc87
4 changed files with 70 additions and 45 deletions

View file

@ -362,6 +362,7 @@ void DivPlatformArcade::tick(bool sysTick) {
chan[i].freq+=chan[i].arpOff<<7;
}
}
chan[i].freq+=OFFSET_LINEAR;
if (chan[i].freq<0) chan[i].freq=0;
if (chan[i].freq>=(95<<7)) chan[i].freq=(95<<7)-1;
immWrite(i+0x28,hScale(chan[i].freq>>7));

View file

@ -22,7 +22,9 @@
#include "fmsharedbase.h"
#define NOTE_LINEAR(x) (((x)<<7)+baseFreqOff+log2(parent->song.tuning/440.0)*12.0*128.0)
#define NOTE_LINEAR(x) ((x)<<7)
#define OFFSET_LINEAR (baseFreqOff+log2(parent->song.tuning/440.0)*12.0*128.0)
class DivPlatformOPM: public DivPlatformFMBase {
protected:

View file

@ -108,6 +108,7 @@ int DivPlatformTX81Z::toFreq(int freq) {
freq>>=1;
block++;
}
if (block>7) return 0x7ff;
return ((block&7)<<8)|(freq&0xff);
}
@ -300,49 +301,51 @@ void DivPlatformTX81Z::tick(bool sysTick) {
}
// fixed pitch
bool freqChangeOp=false;
if (parent->song.linearPitch==2) {
bool freqChangeOp=false;
if (op.egt) {
if (op.sus) {
chan[i].handleArpFmOp(freqChangeOp,0,j); // arp and pitch macros
chan[i].handlePitchFmOp(freqChangeOp,j);
} else {
if (m.ssg.had) { // block and f-num macros
op.dt=m.ssg.val&7;
rWrite(baseAddr+ADDR_MULT_DT,(op.mult&15)|((op.egt?(op.dt&7):dtTable[op.dt&7])<<4));
}
if (m.sus.had) {
op.mult=(m.sus.val&0xff)>>4;
op.dvb=(m.sus.val&0xf);
rWrite(baseAddr+ADDR_MULT_DT,(op.mult&15)|((op.egt?(op.dt&7):dtTable[op.dt&7])<<4));
rWrite(baseAddr+ADDR_WS_FINE,(op.dvb&15)|(op.ws<<4));
if (op.egt) {
if (op.sus) {
chan[i].handleArpFmOp(freqChangeOp,0,j); // arp and pitch macros
chan[i].handlePitchFmOp(freqChangeOp,j);
} else {
if (m.ssg.had) { // block and f-num macros
op.dt=m.ssg.val&7;
rWrite(baseAddr+ADDR_MULT_DT,(op.mult&15)|((op.egt?(op.dt&7):dtTable[op.dt&7])<<4));
}
if (m.sus.had) {
op.mult=(m.sus.val&0xff)>>4;
op.dvb=(m.sus.val&0xf);
rWrite(baseAddr+ADDR_MULT_DT,(op.mult&15)|((op.egt?(op.dt&7):dtTable[op.dt&7])<<4));
rWrite(baseAddr+ADDR_WS_FINE,(op.dvb&15)|(op.ws<<4));
}
}
}
}
if (freqChangeOp) {
int arp=chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff;
int pitch2=chan[i].pitch2;
int fixedArp=chan[i].fixedArp;
if (chan[i].opsState[j].hasOpArp) {
arp=chan[i].opsState[j].fixedArp?chan[i].opsState[j].baseNoteOverride:chan[i].opsState[j].arpOff;
fixedArp=chan[i].opsState[j].fixedArp;
if (freqChangeOp) {
int arp=chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff;
int pitch2=chan[i].pitch2;
int fixedArp=chan[i].fixedArp;
if (chan[i].opsState[j].hasOpArp) {
arp=chan[i].opsState[j].fixedArp?chan[i].opsState[j].baseNoteOverride:chan[i].opsState[j].arpOff;
fixedArp=chan[i].opsState[j].fixedArp;
}
if (chan[i].opsState[j].hasOpPitch) {
pitch2=chan[i].opsState[j].pitch2;
}
int opFreq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,arp,fixedArp,false,2, pitch2,32.0,COLOR_NTSC/chipClock,0);
if (opFreq<0) opFreq=0;
if (opFreq>65280) opFreq=65280;
int freqt=toFreq(opFreq);
op.dt=(freqt>>8)&7;
op.mult=(freqt&0xff)>>4;
op.dvb=(freqt&0xf);
rWrite(baseAddr+ADDR_MULT_DT,(op.mult&15)|((op.egt?(op.dt&7):dtTable[op.dt&7])<<4));
rWrite(baseAddr+ADDR_WS_FINE,(op.dvb&15)|(op.ws<<4));
}
if (chan[i].opsState[j].hasOpPitch) {
pitch2=chan[i].opsState[j].pitch2;
}
int opFreq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,arp,fixedArp,false,2,pitch2,chipClock,(524288.0/4.0)*2093.0/2192.0*chipClock/4000000.0,0);
if (opFreq<0) opFreq=0;
if (opFreq>65280) opFreq=65280;
int freqt=toFreq(opFreq);
op.dt=(freqt>>8)&7;
op.mult=(freqt&0xff)>>4;
op.dvb=(freqt&0xf);
rWrite(baseAddr+ADDR_MULT_DT,(op.mult&15)|((op.egt?(op.dt&7):dtTable[op.dt&7])<<4));
rWrite(baseAddr+ADDR_WS_FINE,(op.dvb&15)|(op.ws<<4));
}
}
}
@ -400,6 +403,7 @@ void DivPlatformTX81Z::tick(bool sysTick) {
chan[i].freq+=chan[i].arpOff<<7;
}
}
chan[i].freq+=OFFSET_LINEAR;
if (chan[i].freq<0) chan[i].freq=0;
if (chan[i].freq>=(95<<7)) chan[i].freq=(95<<7)-1;
immWrite(i+0x28,hScale(chan[i].freq>>7));

View file

@ -4476,14 +4476,20 @@ void FurnaceGUI::insTabFM(DivInstrument* ins) {
op.egt=egtOn;
}
if (egtOn) {
if (ImGui::Checkbox("Pitch control",&susOn)) { PARAMETER
pushWarningColor(susOn && e->song.linearPitch!=2);
if (ImGui::Checkbox(_("Pitch control"),&susOn)) { PARAMETER
op.sus=susOn;
// HACK: reset zoom and scroll in fixed pitch macros so that they draw correctly
ins->std.opMacros[i].ssgMacro.vZoom=-1;
ins->std.opMacros[i].susMacro.vZoom=-1;
}
popWarningColor();
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip(_("Use op's arpeggio and pitch macros control instead of block/f-num macros"));
if (susOn && e->song.linearPitch!=2) {
ImGui::SetTooltip(_("only works on linear pitch! go to Compatibility Flags > Pitch/Playback and set Pitch linearity to Full."));
} else {
ImGui::SetTooltip(_("use op's arpeggio and pitch macros control instead of block/f-num macros"));
}
}
}
if (egtOn && !susOn) {
@ -5239,14 +5245,20 @@ void FurnaceGUI::insTabFM(DivInstrument* ins) {
P(CWSliderScalar("##FINE",ImGuiDataType_U8,&op.dvb,&_ZERO,&_FIFTEEN,tempID)); rightClickable
} else {
bool susOn=op.sus;
if (ImGui::Checkbox("Pitch control",&susOn)) { PARAMETER
pushWarningColor(susOn && e->song.linearPitch!=2);
if (ImGui::Checkbox(_("Pitch control"),&susOn)) { PARAMETER
op.sus=susOn;
// HACK: reset zoom and scroll in fixed pitch macros so that they draw correctly
ins->std.opMacros[i].ssgMacro.vZoom=-1;
ins->std.opMacros[i].susMacro.vZoom=-1;
}
popWarningColor();
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip(_("Use op's arpeggio and pitch macros control instead of block/f-num macros"));
if (susOn && e->song.linearPitch!=2) {
ImGui::SetTooltip(_("only works on linear pitch! go to Compatibility Flags > Pitch/Playback and set Pitch linearity to Full."));
} else {
ImGui::SetTooltip(_("use op's arpeggio and pitch macros control instead of block/f-num macros"));
}
}
}
@ -5556,14 +5568,20 @@ void FurnaceGUI::insTabFM(DivInstrument* ins) {
bool susOn=op.sus;
if (fixedOn) {
ImGui::SameLine();
if (ImGui::Checkbox("Pitch control",&susOn)) { PARAMETER
pushWarningColor(susOn && e->song.linearPitch!=2);
if (ImGui::Checkbox(_("Pitch control"),&susOn)) { PARAMETER
op.sus=susOn;
// HACK: reset zoom and scroll in fixed pitch macros so that they draw correctly
ins->std.opMacros[i].ssgMacro.vZoom=-1;
ins->std.opMacros[i].susMacro.vZoom=-1;
}
popWarningColor();
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip(_("Use op's arpeggio and pitch macros control instead of block/f-num macros"));
if (susOn && e->song.linearPitch!=2) {
ImGui::SetTooltip(_("only works on linear pitch! go to Compatibility Flags > Pitch/Playback and set Pitch linearity to Full."));
} else {
ImGui::SetTooltip(_("use op's arpeggio and pitch macros control instead of block/f-num macros"));
}
}
}
}