diff --git a/extern/pwrnoise/README.md b/extern/pwrnoise/README.md index 0366f408a..b6d9e86d1 100644 --- a/extern/pwrnoise/README.md +++ b/extern/pwrnoise/README.md @@ -1,4 +1,4 @@ # pwrnoise -An emulator for the Power Noise fantasy sound chip, part of the [Hexheld](https://github.com/Hexheld/) fantasy console. +An emulator for the PowerNoise fantasy sound chip, part of the [Hexheld](https://github.com/Hexheld/) fantasy console. Design by [jvsTSX](https://github.com/jvsTSX/), code by scratchminer. \ No newline at end of file diff --git a/src/engine/platform/powernoise.cpp b/src/engine/platform/powernoise.cpp index ef14c06d3..f7393e264 100644 --- a/src/engine/platform/powernoise.cpp +++ b/src/engine/platform/powernoise.cpp @@ -35,6 +35,7 @@ (b.dir ? 0x01 : 0x00)) #define volPan(v, p) (((v * (p >> 4) / 15) << 4) | ((v * (p & 0xf) / 15) & 0xf)) #define mapAmp(a) (((a) * 65535 / 15 - 32768) * (pn.flags & 0x7) / 7) +#define CHIP_DIVIDER 2 const char* regCheatSheetPowerNoise[]={ "ACTL", "00", @@ -174,13 +175,63 @@ void DivPlatformPowerNoise::tick(bool sysTick) { } if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) { - chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,true,0,chan[i].pitch2,chipClock,chan[i].octave); + chan[i].freq = parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,true,0,chan[i].pitch2,chipClock,CHIP_DIVIDER); if (chan[i].freq<0) chan[i].freq=0; - if (chan[i].freq>4095) chan[i].freq=4095; + if (chan[i].freq>0xfffffff) chan[i].freq=0xfffffff; + if(chan[i].freq >= 0x8000000) { + chan[i].octave = 0; + } + else if(chan[i].freq >= 0x4000000) { + chan[i].octave = 1; + } + else if(chan[i].freq >= 0x2000000) { + chan[i].octave = 2; + } + else if(chan[i].freq >= 0x1000000) { + chan[i].octave = 3; + } + if(chan[i].freq >= 0x800000) { + chan[i].octave = 4; + } + else if(chan[i].freq >= 0x400000) { + chan[i].octave = 5; + } + else if(chan[i].freq >= 0x200000) { + chan[i].octave = 6; + } + else if(chan[i].freq >= 0x100000) { + chan[i].octave = 7; + } + if(chan[i].freq >= 0x800000) { + chan[i].octave = 8; + } + else if(chan[i].freq >= 0x400000) { + chan[i].octave = 9; + } + else if(chan[i].freq >= 0x200000) { + chan[i].octave = 10; + } + else if(chan[i].freq >= 0x100000) { + chan[i].octave = 11; + } + if(chan[i].freq >= 0x8000) { + chan[i].octave = 12; + } + else if(chan[i].freq >= 0x4000) { + chan[i].octave = 13; + } + else if(chan[i].freq >= 0x2000) { + chan[i].octave = 14; + } + else { + chan[i].octave = 15; + } + chan[i].freq = 0xfff-(chan[i].freq>>chan[i].octave); + chan[i].octave = 15 - chan[i].octave; - cWrite(i,0x01,(4095-chan[i].freq)&0xff); - cWrite(i,0x02,((4095-chan[i].freq)>>8) | (chan[i].octave<<4)); + cWrite(i,0x01,chan[i].freq&0xff); + cWrite(i,0x02,(chan[i].freq>>8) | (chan[i].octave<<4)); if (chan[i].keyOn) { if(chan[i].slope) { @@ -227,14 +278,7 @@ int DivPlatformPowerNoise::dispatch(DivCommand c) { if (ins->type==DIV_INS_POWER_NOISE) { if (skipRegisterWrites) break; if (c.value!=DIV_NOTE_NULL) { - int baseFreq, divider; - for (divider = 0; divider < 16; divider++) { - baseFreq = round(parent->calcBaseFreq(chipClock,2<calcBaseFreq(chipClock,2<chan[c.chan].baseFreq || dividerchan[c.chan].baseFreq) { chan[c.chan].baseFreq+=c.value; - if (chan[c.chan].baseFreq > 4095 && chan[c.chan].octave > 0) { - chan[c.chan].octave--; - chan[c.chan].baseFreq %= 4096; + if (chan[c.chan].baseFreq > 0xfffffff) { + chan[c.chan].baseFreq = 0xfffffff; } - if (chan[c.chan].baseFreq>=destFreq || chan[c.chan].octave=destFreq) { chan[c.chan].baseFreq=destFreq; - chan[c.chan].octave=divider; return2=true; } } else { chan[c.chan].baseFreq-=c.value; - if (chan[c.chan].baseFreq < 0 && chan[c.chan].octave < 15) { - chan[c.chan].octave++; - chan[c.chan].baseFreq = (chan[c.chan].baseFreq + 4096) % 4096; + if (chan[c.chan].baseFreq < 0) { + chan[c.chan].baseFreq = 0; } - if (chan[c.chan].baseFreq<=destFreq || chan[c.chan].octave>divider) { + if (chan[c.chan].baseFreq<=destFreq) { chan[c.chan].baseFreq=destFreq; - chan[c.chan].octave=divider; return2=true; } } @@ -327,13 +363,7 @@ int DivPlatformPowerNoise::dispatch(DivCommand c) { case DIV_CMD_LEGATO: { int whatAMess = c.value+((HACKY_LEGATO_MESS)?(chan[c.chan].std.arp.val):(0)); - int baseFreq, divider; - for (divider = 0; divider < 16; divider++) { - baseFreq = round(parent->calcBaseFreq(chipClock,2<song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_POWER_NOISE)); } if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will && !NEW_ARP_STRAT) { - int baseFreq, divider; - for (divider = 0; divider < 16; divider++) { - baseFreq = round(parent->calcBaseFreq(chipClock,2<