dev200 - new sample offset effects

90xx/91yy/92zz set offset zzyyxx
This commit is contained in:
tildearrow 2024-04-23 14:36:06 -05:00
parent 2b95da8d10
commit 7a217ccdb1
5 changed files with 43 additions and 12 deletions

View file

@ -156,7 +156,17 @@ const char* DivEngine::getEffectDesc(unsigned char effect, int chan, bool notNul
return "FFxx: Stop song"; return "FFxx: Stop song";
default: default:
if ((effect&0xf0)==0x90) { if ((effect&0xf0)==0x90) {
return "9xxx: Set sample offset*256"; if (song.oldSampleOffset) {
return "9xxx: Set sample offset*256";
}
switch (effect) {
case 0x90:
return "90xx: Set sample offset (first byte)";
case 0x91:
return "91xx: Set sample offset (second byte, ×256)";
case 0x92:
return "92xx: Set sample offset (third byte, ×65536)";
}
} else if (chan>=0 && chan<chans) { } else if (chan>=0 && chan<chans) {
DivSysDef* sysDef=sysDefs[sysOfChan[chan]]; DivSysDef* sysDef=sysDefs[sysOfChan[chan]];
auto iter=sysDef->effectHandlers.find(effect); auto iter=sysDef->effectHandlers.find(effect);
@ -562,8 +572,8 @@ void DivEngine::initSongWithDesc(const char* description, bool inBase64, bool ol
// extra attributes // extra attributes
song.subsong[0]->hz=c.getDouble("tickRate",60.0); song.subsong[0]->hz=c.getDouble("tickRate",60.0);
if (song.subsong[0]->hz<1.0) song->subsong[0]->hz=1.0; if (song.subsong[0]->hz<1.0) song.subsong[0]->hz=1.0;
if (song.subsong[0]->hz>999.0) song->subsong[0]->hz=999.0; if (song.subsong[0]->hz>999.0) song.subsong[0]->hz=999.0;
song.author=getConfString("defaultAuthorName",""); song.author=getConfString("defaultAuthorName","");
} }

View file

@ -54,8 +54,8 @@ class DivWorkPool;
#define DIV_UNSTABLE #define DIV_UNSTABLE
#define DIV_VERSION "dev199" #define DIV_VERSION "dev200"
#define DIV_ENGINE_VERSION 199 #define DIV_ENGINE_VERSION 200
// for imports // for imports
#define DIV_VERSION_MOD 0xff01 #define DIV_VERSION_MOD 0xff01
#define DIV_VERSION_FC 0xff02 #define DIV_VERSION_FC 0xff02
@ -105,9 +105,10 @@ struct DivChannelState {
int delayOrder, delayRow, retrigSpeed, retrigTick; int delayOrder, delayRow, retrigSpeed, retrigTick;
int vibratoDepth, vibratoRate, vibratoPos, vibratoPosGiant, vibratoDir, vibratoFine; int vibratoDepth, vibratoRate, vibratoPos, vibratoPosGiant, vibratoDir, vibratoFine;
int tremoloDepth, tremoloRate, tremoloPos; int tremoloDepth, tremoloRate, tremoloPos;
int sampleOff;
unsigned char arp, arpStage, arpTicks, panL, panR, panRL, panRR, lastVibrato, lastPorta, cutType; unsigned char arp, arpStage, arpTicks, panL, panR, panRL, panRR, lastVibrato, lastPorta, cutType;
bool doNote, legato, portaStop, keyOn, keyOff, nowYouCanStop, stopOnOff, releasing; bool doNote, legato, portaStop, keyOn, keyOff, nowYouCanStop, stopOnOff, releasing;
bool arpYield, delayLocked, inPorta, scheduledSlideReset, shorthandPorta, wasShorthandPorta, noteOnInhibit, resetArp; bool arpYield, delayLocked, inPorta, scheduledSlideReset, shorthandPorta, wasShorthandPorta, noteOnInhibit, resetArp, sampleOffSet;
bool wentThroughNote, goneThroughNote; bool wentThroughNote, goneThroughNote;
int midiNote, curMidiNote, midiPitch; int midiNote, curMidiNote, midiPitch;
@ -141,6 +142,7 @@ struct DivChannelState {
tremoloDepth(0), tremoloDepth(0),
tremoloRate(0), tremoloRate(0),
tremoloPos(0), tremoloPos(0),
sampleOff(0),
arp(0), arp(0),
arpStage(-1), arpStage(-1),
arpTicks(1), arpTicks(1),
@ -167,6 +169,7 @@ struct DivChannelState {
wasShorthandPorta(false), wasShorthandPorta(false),
noteOnInhibit(false), noteOnInhibit(false),
resetArp(false), resetArp(false),
sampleOffSet(false),
wentThroughNote(false), wentThroughNote(false),
goneThroughNote(false), goneThroughNote(false),
midiNote(-1), midiNote(-1),

View file

@ -861,6 +861,9 @@ bool DivEngine::loadFur(unsigned char* file, size_t len, int variantID) {
if (ds.version<191) { if (ds.version<191) {
ds.oldAlwaysSetVolume=true; ds.oldAlwaysSetVolume=true;
} }
if (ds.version<200) {
ds.oldSampleOffset=true;
}
ds.isDMF=false; ds.isDMF=false;
reader.readS(); // reserved reader.readS(); // reserved
@ -1414,7 +1417,9 @@ bool DivEngine::loadFur(unsigned char* file, size_t len, int variantID) {
} else { } else {
reader.readC(); reader.readC();
} }
for (int i=0; i<1; i++) { if (ds.version>=200) {
ds.oldSampleOffset=reader.readC();
} else {
reader.readC(); reader.readC();
} }
} }
@ -2402,9 +2407,7 @@ SafeWriter* DivEngine::saveFur(bool notPrimary, bool newPatternFormat) {
w->writeC(song.resetArpPhaseOnNewNote); w->writeC(song.resetArpPhaseOnNewNote);
w->writeC(song.ceilVolumeScaling); w->writeC(song.ceilVolumeScaling);
w->writeC(song.oldAlwaysSetVolume); w->writeC(song.oldAlwaysSetVolume);
for (int i=0; i<1; i++) { w->writeC(song.oldSampleOffset);
w->writeC(0);
}
// speeds of first song // speeds of first song
w->writeC(subSong->speeds.len); w->writeC(subSong->speeds.len);

View file

@ -654,6 +654,7 @@ void DivEngine::processRow(int i, bool afterDelay) {
bool calledPorta=false; bool calledPorta=false;
bool panChanged=false; bool panChanged=false;
bool surroundPanChanged=false; bool surroundPanChanged=false;
bool sampleOffSet=false;
// effects // effects
for (int j=0; j<curPat[i].effectCols; j++) { for (int j=0; j<curPat[i].effectCols; j++) {
@ -889,7 +890,15 @@ void DivEngine::processRow(int i, bool afterDelay) {
case 0x94: case 0x95: case 0x96: case 0x97: case 0x94: case 0x95: case 0x96: case 0x97:
case 0x98: case 0x99: case 0x9a: case 0x9b: case 0x98: case 0x99: case 0x9a: case 0x9b:
case 0x9c: case 0x9d: case 0x9e: case 0x9f: // set samp. pos case 0x9c: case 0x9d: case 0x9e: case 0x9f: // set samp. pos
dispatchCmd(DivCommand(DIV_CMD_SAMPLE_POS,i,(((effect&0x0f)<<8)|effectVal)*256)); if (song.oldSampleOffset) {
dispatchCmd(DivCommand(DIV_CMD_SAMPLE_POS,i,(((effect&0x0f)<<8)|effectVal)*256));
} else {
if (effect<0x93) {
chan[i].sampleOff&=~(0xff<<((effect-0x90)<<3));
chan[i].sampleOff|=effectVal<<((effect-0x90)<<3);
sampleOffSet=true;
}
}
break; break;
case 0xc0: case 0xc1: case 0xc2: case 0xc3: // set Hz case 0xc0: case 0xc1: case 0xc2: case 0xc3: // set Hz
divider=(double)(((effect&0x3)<<8)|effectVal); divider=(double)(((effect&0x3)<<8)|effectVal);
@ -1113,6 +1122,10 @@ void DivEngine::processRow(int i, bool afterDelay) {
} }
} }
if (sampleOffSet) {
dispatchCmd(DivCommand(DIV_CMD_SAMPLE_POS,i,chan[i].sampleOff));
}
if (panChanged) { if (panChanged) {
dispatchCmd(DivCommand(DIV_CMD_PANNING,i,chan[i].panL,chan[i].panR)); dispatchCmd(DivCommand(DIV_CMD_PANNING,i,chan[i].panL,chan[i].panR));
} }

View file

@ -333,6 +333,7 @@ struct DivSong {
bool resetArpPhaseOnNewNote; bool resetArpPhaseOnNewNote;
bool ceilVolumeScaling; bool ceilVolumeScaling;
bool oldAlwaysSetVolume; bool oldAlwaysSetVolume;
bool oldSampleOffset;
std::vector<DivInstrument*> ins; std::vector<DivInstrument*> ins;
std::vector<DivWavetable*> wave; std::vector<DivWavetable*> wave;
@ -456,7 +457,8 @@ struct DivSong {
oldDPCM(false), oldDPCM(false),
resetArpPhaseOnNewNote(false), resetArpPhaseOnNewNote(false),
ceilVolumeScaling(false), ceilVolumeScaling(false),
oldAlwaysSetVolume(false) { oldAlwaysSetVolume(false),
oldSampleOffset(false) {
for (int i=0; i<DIV_MAX_CHIPS; i++) { for (int i=0; i<DIV_MAX_CHIPS; i++) {
system[i]=DIV_SYSTEM_NULL; system[i]=DIV_SYSTEM_NULL;
systemVol[i]=1.0; systemVol[i]=1.0;