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";
default:
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) {
DivSysDef* sysDef=sysDefs[sysOfChan[chan]];
auto iter=sysDef->effectHandlers.find(effect);
@ -562,8 +572,8 @@ void DivEngine::initSongWithDesc(const char* description, bool inBase64, bool ol
// extra attributes
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>999.0) song->subsong[0]->hz=999.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;
song.author=getConfString("defaultAuthorName","");
}

View file

@ -54,8 +54,8 @@ class DivWorkPool;
#define DIV_UNSTABLE
#define DIV_VERSION "dev199"
#define DIV_ENGINE_VERSION 199
#define DIV_VERSION "dev200"
#define DIV_ENGINE_VERSION 200
// for imports
#define DIV_VERSION_MOD 0xff01
#define DIV_VERSION_FC 0xff02
@ -105,9 +105,10 @@ struct DivChannelState {
int delayOrder, delayRow, retrigSpeed, retrigTick;
int vibratoDepth, vibratoRate, vibratoPos, vibratoPosGiant, vibratoDir, vibratoFine;
int tremoloDepth, tremoloRate, tremoloPos;
int sampleOff;
unsigned char arp, arpStage, arpTicks, panL, panR, panRL, panRR, lastVibrato, lastPorta, cutType;
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;
int midiNote, curMidiNote, midiPitch;
@ -141,6 +142,7 @@ struct DivChannelState {
tremoloDepth(0),
tremoloRate(0),
tremoloPos(0),
sampleOff(0),
arp(0),
arpStage(-1),
arpTicks(1),
@ -167,6 +169,7 @@ struct DivChannelState {
wasShorthandPorta(false),
noteOnInhibit(false),
resetArp(false),
sampleOffSet(false),
wentThroughNote(false),
goneThroughNote(false),
midiNote(-1),

View file

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

View file

@ -654,6 +654,7 @@ void DivEngine::processRow(int i, bool afterDelay) {
bool calledPorta=false;
bool panChanged=false;
bool surroundPanChanged=false;
bool sampleOffSet=false;
// effects
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 0x98: case 0x99: case 0x9a: case 0x9b:
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;
case 0xc0: case 0xc1: case 0xc2: case 0xc3: // set Hz
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) {
dispatchCmd(DivCommand(DIV_CMD_PANNING,i,chan[i].panL,chan[i].panR));
}

View file

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