mirror of
https://github.com/tildearrow/furnace.git
synced 2024-11-05 04:15:05 +00:00
fix bug caused by new renderSamples approach
when doing switchMaster
This commit is contained in:
parent
a7b8f81da7
commit
dbe9bf25e7
4 changed files with 86 additions and 9 deletions
|
@ -2366,6 +2366,7 @@ bool DivEngine::switchMaster() {
|
|||
} else {
|
||||
return false;
|
||||
}
|
||||
renderSamples();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,8 @@
|
|||
#include "nes.h"
|
||||
#include "sound/nes/cpu_inline.h"
|
||||
#include "../engine.h"
|
||||
#include <cstddef>
|
||||
#include "../../ta-log.h"
|
||||
#include <stddef.h>
|
||||
#include <math.h>
|
||||
|
||||
struct _nla_table nla_table;
|
||||
|
@ -75,6 +76,9 @@ const char* DivPlatformNES::getEffectName(unsigned char effect) {
|
|||
case 0x14:
|
||||
return "14xy: Sweep down (x: time; y: shift)";
|
||||
break;
|
||||
case 0x18:
|
||||
return "18xx: Select PCM/DPCM mode (0: PCM; 1: DPCM)";
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
@ -89,7 +93,7 @@ void DivPlatformNES::doWrite(unsigned short addr, unsigned char data) {
|
|||
}
|
||||
|
||||
#define doPCM \
|
||||
if (dacSample!=-1) { \
|
||||
if (!dpcmMode && dacSample!=-1) { \
|
||||
dacPeriod+=dacRate; \
|
||||
if (dacPeriod>=rate) { \
|
||||
DivSample* s=parent->getSample(dacSample); \
|
||||
|
@ -344,10 +348,10 @@ int DivPlatformNES::dispatch(DivCommand c) {
|
|||
dacSample=ins->amiga.initSample;
|
||||
if (dacSample<0 || dacSample>=parent->song.sampleLen) {
|
||||
dacSample=-1;
|
||||
if (dumpWrites) addWrite(0xffff0002,0);
|
||||
if (dumpWrites && !dpcmMode) addWrite(0xffff0002,0);
|
||||
break;
|
||||
} else {
|
||||
if (dumpWrites) addWrite(0xffff0000,dacSample);
|
||||
if (dumpWrites && !dpcmMode) addWrite(0xffff0000,dacSample);
|
||||
}
|
||||
dacPos=0;
|
||||
dacPeriod=0;
|
||||
|
@ -366,16 +370,29 @@ int DivPlatformNES::dispatch(DivCommand c) {
|
|||
dacSample=12*sampleBank+chan[c.chan].note%12;
|
||||
if (dacSample>=parent->song.sampleLen) {
|
||||
dacSample=-1;
|
||||
if (dumpWrites) addWrite(0xffff0002,0);
|
||||
if (dumpWrites && !dpcmMode) addWrite(0xffff0002,0);
|
||||
break;
|
||||
} else {
|
||||
if (dumpWrites) addWrite(0xffff0000,dacSample);
|
||||
if (dumpWrites && !dpcmMode) addWrite(0xffff0000,dacSample);
|
||||
}
|
||||
dacPos=0;
|
||||
dacPeriod=0;
|
||||
dacRate=parent->getSample(dacSample)->rate;
|
||||
if (dumpWrites) addWrite(0xffff0001,dacRate);
|
||||
if (dumpWrites && !dpcmMode) addWrite(0xffff0001,dacRate);
|
||||
chan[c.chan].furnaceDac=false;
|
||||
if (dpcmMode && !skipRegisterWrites) {
|
||||
unsigned int dpcmAddr=parent->getSample(dacSample)->offDPCM;
|
||||
unsigned int dpcmLen=(parent->getSample(dacSample)->lengthDPCM+15)>>4;
|
||||
if (dpcmLen>255) dpcmLen=255;
|
||||
// write DPCM
|
||||
rWrite(0x4015,15);
|
||||
rWrite(0x4010,15);
|
||||
rWrite(0x4012,(dpcmAddr>>6)&0xff);
|
||||
rWrite(0x4013,dpcmLen&0xff);
|
||||
rWrite(0x4015,31);
|
||||
dpcmBank=dpcmAddr>>14;
|
||||
logV("writing DPCM: %x %x",dpcmAddr,dpcmLen);
|
||||
}
|
||||
}
|
||||
break;
|
||||
} else if (c.chan==3) { // noise
|
||||
|
@ -484,6 +501,10 @@ int DivPlatformNES::dispatch(DivCommand c) {
|
|||
break;
|
||||
case DIV_CMD_NES_DMC:
|
||||
rWrite(0x4011,c.value&0x7f);
|
||||
if (dumpWrites && dpcmMode) addWrite(0xffff0002,0);
|
||||
break;
|
||||
case DIV_CMD_SAMPLE_MODE:
|
||||
dpcmMode=c.value;
|
||||
break;
|
||||
case DIV_CMD_SAMPLE_BANK:
|
||||
sampleBank=c.value;
|
||||
|
@ -568,6 +589,8 @@ void DivPlatformNES::reset() {
|
|||
dacRate=0;
|
||||
dacSample=-1;
|
||||
sampleBank=0;
|
||||
dpcmBank=0;
|
||||
dpcmMode=false;
|
||||
|
||||
if (useNP) {
|
||||
nes1_NP->Reset();
|
||||
|
@ -638,8 +661,46 @@ void DivPlatformNES::setNSFPlay(bool use) {
|
|||
}
|
||||
|
||||
unsigned char DivPlatformNES::readDMC(unsigned short addr) {
|
||||
printf("read from DMC! %x\n",addr);
|
||||
return 0;
|
||||
return dpcmMem[(addr&0x3fff)|((dpcmBank&15)<<14)];
|
||||
}
|
||||
|
||||
const void* DivPlatformNES::getSampleMem(int index) {
|
||||
return index==0?dpcmMem:NULL;
|
||||
}
|
||||
|
||||
size_t DivPlatformNES::getSampleMemCapacity(int index) {
|
||||
return index==0?262144:0;
|
||||
}
|
||||
|
||||
size_t DivPlatformNES::getSampleMemUsage(int index) {
|
||||
return index==0?dpcmMemLen:0;
|
||||
}
|
||||
|
||||
void DivPlatformNES::renderSamples() {
|
||||
memset(dpcmMem,0,getSampleMemCapacity(0));
|
||||
|
||||
size_t memPos=0;
|
||||
for (int i=0; i<parent->song.sampleLen; i++) {
|
||||
DivSample* s=parent->song.sample[i];
|
||||
int paddedLen=(s->lengthDPCM+63)&(~0xff);
|
||||
logV("%d padded length: %d",i,paddedLen);
|
||||
if ((memPos&0x4000)!=((memPos+paddedLen)&0x4000)) {
|
||||
memPos=(memPos+0x3fff)&0x4000;
|
||||
}
|
||||
if (memPos>=getSampleMemCapacity(0)) {
|
||||
logW("out of DPCM memory for sample %d!",i);
|
||||
break;
|
||||
}
|
||||
if (memPos+paddedLen>=getSampleMemCapacity(0)) {
|
||||
memcpy(dpcmMem+memPos,s->dataDPCM,getSampleMemCapacity(0)-memPos);
|
||||
logW("out of DPCM memory for sample %d!",i);
|
||||
} else {
|
||||
memcpy(dpcmMem+memPos,s->dataDPCM,paddedLen);
|
||||
}
|
||||
s->offDPCM=memPos;
|
||||
memPos+=paddedLen;
|
||||
}
|
||||
dpcmMemLen=memPos;
|
||||
}
|
||||
|
||||
int DivPlatformNES::init(DivEngine* p, int channels, int sugRate, unsigned int flags) {
|
||||
|
@ -669,6 +730,10 @@ int DivPlatformNES::init(DivEngine* p, int channels, int sugRate, unsigned int f
|
|||
}
|
||||
setFlags(flags);
|
||||
|
||||
dpcmMem=new unsigned char[262144];
|
||||
dpcmMemLen=0;
|
||||
dpcmBank=0;
|
||||
|
||||
init_nla_table(500,500);
|
||||
reset();
|
||||
return 5;
|
||||
|
|
|
@ -64,9 +64,13 @@ class DivPlatformNES: public DivDispatch {
|
|||
int dacPeriod, dacRate;
|
||||
unsigned int dacPos, dacAntiClick;
|
||||
int dacSample;
|
||||
unsigned char* dpcmMem;
|
||||
size_t dpcmMemLen;
|
||||
unsigned char dpcmBank;
|
||||
unsigned char sampleBank;
|
||||
unsigned char writeOscBuf;
|
||||
unsigned char apuType;
|
||||
bool dpcmMode;
|
||||
bool dacAntiClickOn;
|
||||
bool useNP;
|
||||
struct NESAPU* nes;
|
||||
|
@ -101,6 +105,10 @@ class DivPlatformNES: public DivDispatch {
|
|||
void poke(std::vector<DivRegWrite>& wlist);
|
||||
const char** getRegisterSheet();
|
||||
const char* getEffectName(unsigned char effect);
|
||||
const void* getSampleMem(int index);
|
||||
size_t getSampleMemCapacity(int index);
|
||||
size_t getSampleMemUsage(int index);
|
||||
void renderSamples();
|
||||
int init(DivEngine* parent, int channels, int sugRate, unsigned int flags);
|
||||
void quit();
|
||||
~DivPlatformNES();
|
||||
|
|
|
@ -330,6 +330,9 @@ bool DivEngine::perSystemEffect(int ch, unsigned char effect, unsigned char effe
|
|||
case 0x14: // sweep down
|
||||
dispatchCmd(DivCommand(DIV_CMD_NES_SWEEP,ch,1,effectVal));
|
||||
break;
|
||||
case 0x18: // DPCM mode
|
||||
dispatchCmd(DivCommand(DIV_CMD_SAMPLE_MODE,ch,effectVal));
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue