fix bug caused by new renderSamples approach
when doing switchMaster
This commit is contained in:
parent
a7b8f81da7
commit
dbe9bf25e7
|
@ -2366,6 +2366,7 @@ bool DivEngine::switchMaster() {
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
renderSamples();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,8 @@
|
||||||
#include "nes.h"
|
#include "nes.h"
|
||||||
#include "sound/nes/cpu_inline.h"
|
#include "sound/nes/cpu_inline.h"
|
||||||
#include "../engine.h"
|
#include "../engine.h"
|
||||||
#include <cstddef>
|
#include "../../ta-log.h"
|
||||||
|
#include <stddef.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
struct _nla_table nla_table;
|
struct _nla_table nla_table;
|
||||||
|
@ -75,6 +76,9 @@ const char* DivPlatformNES::getEffectName(unsigned char effect) {
|
||||||
case 0x14:
|
case 0x14:
|
||||||
return "14xy: Sweep down (x: time; y: shift)";
|
return "14xy: Sweep down (x: time; y: shift)";
|
||||||
break;
|
break;
|
||||||
|
case 0x18:
|
||||||
|
return "18xx: Select PCM/DPCM mode (0: PCM; 1: DPCM)";
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -89,7 +93,7 @@ void DivPlatformNES::doWrite(unsigned short addr, unsigned char data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#define doPCM \
|
#define doPCM \
|
||||||
if (dacSample!=-1) { \
|
if (!dpcmMode && dacSample!=-1) { \
|
||||||
dacPeriod+=dacRate; \
|
dacPeriod+=dacRate; \
|
||||||
if (dacPeriod>=rate) { \
|
if (dacPeriod>=rate) { \
|
||||||
DivSample* s=parent->getSample(dacSample); \
|
DivSample* s=parent->getSample(dacSample); \
|
||||||
|
@ -344,10 +348,10 @@ int DivPlatformNES::dispatch(DivCommand c) {
|
||||||
dacSample=ins->amiga.initSample;
|
dacSample=ins->amiga.initSample;
|
||||||
if (dacSample<0 || dacSample>=parent->song.sampleLen) {
|
if (dacSample<0 || dacSample>=parent->song.sampleLen) {
|
||||||
dacSample=-1;
|
dacSample=-1;
|
||||||
if (dumpWrites) addWrite(0xffff0002,0);
|
if (dumpWrites && !dpcmMode) addWrite(0xffff0002,0);
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
if (dumpWrites) addWrite(0xffff0000,dacSample);
|
if (dumpWrites && !dpcmMode) addWrite(0xffff0000,dacSample);
|
||||||
}
|
}
|
||||||
dacPos=0;
|
dacPos=0;
|
||||||
dacPeriod=0;
|
dacPeriod=0;
|
||||||
|
@ -366,16 +370,29 @@ int DivPlatformNES::dispatch(DivCommand c) {
|
||||||
dacSample=12*sampleBank+chan[c.chan].note%12;
|
dacSample=12*sampleBank+chan[c.chan].note%12;
|
||||||
if (dacSample>=parent->song.sampleLen) {
|
if (dacSample>=parent->song.sampleLen) {
|
||||||
dacSample=-1;
|
dacSample=-1;
|
||||||
if (dumpWrites) addWrite(0xffff0002,0);
|
if (dumpWrites && !dpcmMode) addWrite(0xffff0002,0);
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
if (dumpWrites) addWrite(0xffff0000,dacSample);
|
if (dumpWrites && !dpcmMode) addWrite(0xffff0000,dacSample);
|
||||||
}
|
}
|
||||||
dacPos=0;
|
dacPos=0;
|
||||||
dacPeriod=0;
|
dacPeriod=0;
|
||||||
dacRate=parent->getSample(dacSample)->rate;
|
dacRate=parent->getSample(dacSample)->rate;
|
||||||
if (dumpWrites) addWrite(0xffff0001,dacRate);
|
if (dumpWrites && !dpcmMode) addWrite(0xffff0001,dacRate);
|
||||||
chan[c.chan].furnaceDac=false;
|
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;
|
break;
|
||||||
} else if (c.chan==3) { // noise
|
} else if (c.chan==3) { // noise
|
||||||
|
@ -484,6 +501,10 @@ int DivPlatformNES::dispatch(DivCommand c) {
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_NES_DMC:
|
case DIV_CMD_NES_DMC:
|
||||||
rWrite(0x4011,c.value&0x7f);
|
rWrite(0x4011,c.value&0x7f);
|
||||||
|
if (dumpWrites && dpcmMode) addWrite(0xffff0002,0);
|
||||||
|
break;
|
||||||
|
case DIV_CMD_SAMPLE_MODE:
|
||||||
|
dpcmMode=c.value;
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_SAMPLE_BANK:
|
case DIV_CMD_SAMPLE_BANK:
|
||||||
sampleBank=c.value;
|
sampleBank=c.value;
|
||||||
|
@ -568,6 +589,8 @@ void DivPlatformNES::reset() {
|
||||||
dacRate=0;
|
dacRate=0;
|
||||||
dacSample=-1;
|
dacSample=-1;
|
||||||
sampleBank=0;
|
sampleBank=0;
|
||||||
|
dpcmBank=0;
|
||||||
|
dpcmMode=false;
|
||||||
|
|
||||||
if (useNP) {
|
if (useNP) {
|
||||||
nes1_NP->Reset();
|
nes1_NP->Reset();
|
||||||
|
@ -638,8 +661,46 @@ void DivPlatformNES::setNSFPlay(bool use) {
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char DivPlatformNES::readDMC(unsigned short addr) {
|
unsigned char DivPlatformNES::readDMC(unsigned short addr) {
|
||||||
printf("read from DMC! %x\n",addr);
|
return dpcmMem[(addr&0x3fff)|((dpcmBank&15)<<14)];
|
||||||
return 0;
|
}
|
||||||
|
|
||||||
|
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) {
|
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);
|
setFlags(flags);
|
||||||
|
|
||||||
|
dpcmMem=new unsigned char[262144];
|
||||||
|
dpcmMemLen=0;
|
||||||
|
dpcmBank=0;
|
||||||
|
|
||||||
init_nla_table(500,500);
|
init_nla_table(500,500);
|
||||||
reset();
|
reset();
|
||||||
return 5;
|
return 5;
|
||||||
|
|
|
@ -64,9 +64,13 @@ class DivPlatformNES: public DivDispatch {
|
||||||
int dacPeriod, dacRate;
|
int dacPeriod, dacRate;
|
||||||
unsigned int dacPos, dacAntiClick;
|
unsigned int dacPos, dacAntiClick;
|
||||||
int dacSample;
|
int dacSample;
|
||||||
|
unsigned char* dpcmMem;
|
||||||
|
size_t dpcmMemLen;
|
||||||
|
unsigned char dpcmBank;
|
||||||
unsigned char sampleBank;
|
unsigned char sampleBank;
|
||||||
unsigned char writeOscBuf;
|
unsigned char writeOscBuf;
|
||||||
unsigned char apuType;
|
unsigned char apuType;
|
||||||
|
bool dpcmMode;
|
||||||
bool dacAntiClickOn;
|
bool dacAntiClickOn;
|
||||||
bool useNP;
|
bool useNP;
|
||||||
struct NESAPU* nes;
|
struct NESAPU* nes;
|
||||||
|
@ -101,6 +105,10 @@ class DivPlatformNES: public DivDispatch {
|
||||||
void poke(std::vector<DivRegWrite>& wlist);
|
void poke(std::vector<DivRegWrite>& wlist);
|
||||||
const char** getRegisterSheet();
|
const char** getRegisterSheet();
|
||||||
const char* getEffectName(unsigned char effect);
|
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);
|
int init(DivEngine* parent, int channels, int sugRate, unsigned int flags);
|
||||||
void quit();
|
void quit();
|
||||||
~DivPlatformNES();
|
~DivPlatformNES();
|
||||||
|
|
|
@ -330,6 +330,9 @@ bool DivEngine::perSystemEffect(int ch, unsigned char effect, unsigned char effe
|
||||||
case 0x14: // sweep down
|
case 0x14: // sweep down
|
||||||
dispatchCmd(DivCommand(DIV_CMD_NES_SWEEP,ch,1,effectVal));
|
dispatchCmd(DivCommand(DIV_CMD_NES_SWEEP,ch,1,effectVal));
|
||||||
break;
|
break;
|
||||||
|
case 0x18: // DPCM mode
|
||||||
|
dispatchCmd(DivCommand(DIV_CMD_SAMPLE_MODE,ch,effectVal));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue