ref: 108c333ecdfd8287e12f39f858347db64d33f2f7
parent: aaa773b416d6de796d233caffb15fa78ad8b2a90
author: Olav Sørensen <olav.sorensen@live.no>
date: Tue Mar 31 17:40:07 EDT 2020
Pushed v1.15 code - More improvements to S3M loader. Fixes "satellite one.s3m" and other S3Ms. - Up/down pushbutton delay has been increased even more, to prevent accidentally skipping too much. - Some other small miscellaneous changes not worth of a mention
--- a/src/ft2_about.c
+++ b/src/ft2_about.c
@@ -9,7 +9,7 @@
// ported from original FT2 code
-#define NUM_STARS 512
+#define NUM_STARS 1000
#define ABOUT_SCREEN_W 626
#define ABOUT_SCREEN_H 167
#define ABOUT_LOGO_W 449
@@ -53,7 +53,7 @@
randSeed *= 134775813;
randSeed += 1;
- r = (int32_t)(((int64_t)randSeed * l) >> 32);
+ r = ((int64_t)randSeed * l) >> 32;
return r;
}
@@ -68,13 +68,13 @@
sc = sin32767[a.z >> 6];
cc = cos32767[a.z >> 6];
- mat->x.x = ((ca * cc) >> 16) + (((sc * ((sa * sb) >> 16)) >> 16) << 1);
+ mat->x.x = ((ca * cc) >> 16) + ((sc * ((sa * sb) >> 16)) >> (16-1));
mat->y.x = (sa * cb) >> 16;
- mat->z.x = (((cc * ((sa * sb) >> 16)) >> 16) << 1) - ((ca * sc) >> 16);
+ mat->z.x = ((cc * ((sa * sb) >> 16)) >> (16-1)) - ((ca * sc) >> 16);
- mat->x.y = (((sc * ((ca * sb) >> 16)) >> 16) << 1) - ((sa * cc) >> 16);
+ mat->x.y = ((sc * ((ca * sb) >> 16)) >> (16-1)) - ((sa * cc) >> 16);
mat->y.y = (ca * cb) >> 16;
- mat->z.y = ((sa * sc) >> 16) + (((cc * ((ca * sb) >> 16)) >> 16) << 1);
+ mat->z.y = ((sa * sc) >> 16) + ((cc * ((ca * sb) >> 16)) >> (16-1));
mat->x.z = (cb * sc) >> 16;
mat->y.z = 0 - (sb >> 1);
@@ -167,8 +167,8 @@
static void realStars(void)
{
uint8_t col;
- int16_t x, y, z, xx, xy, xz, yx, yy, yz, zx, zy, zz;
- int32_t screenBufferPos;
+ int16_t z, xx, xy, xz, yx, yy, yz, zx, zy, zz;
+ int32_t x, y, zMul, screenBufferPos;
vector_t *star;
xx = starmat.x.x; xy = starmat.x.y; xz = starmat.x.z;
@@ -190,26 +190,27 @@
star = &starcrd[i];
star->z += hastighet;
- z = ((xz * star->x) >> 16) + ((yz * star->y) >> 16) + ((zz * star->z) >> 16);
+ z = ((xz * star->x) + (yz * star->y) + (zz * star->z)) >> 16;
z += 9000;
- if (z <= 100)
- continue;
+ if (z <= 100) continue;
+ zMul = 0xFFFFFFFF / z; // 8bitbubsy: optimization
+
+ y = ((xy * star->x) + (yy * star->y) + (zy * star->z)) >> (16-7);
+ y = ((int64_t)y * zMul) >> 32;
+ y += (2+ABOUT_SCREEN_H)/2;
+ if ((uint32_t)y > 2+ABOUT_SCREEN_H) continue;
- y = ((xy * star->x) >> 16) + ((yy * star->y) >> 16) + ((zy * star->z) >> 16);
- y = (int16_t)((y << 7) / z) + 84;
- if ((uint16_t)y >= 173-6)
- continue;
+ x = ((xx * star->x) + (yx * star->y) + (zx * star->z)) >> (16-7);
+ x += x >> 2; // x *= 1.25
+ x = ((int64_t)x * zMul) >> 32;
+ x += (2+ABOUT_SCREEN_W)/2;
+ if ((uint32_t)x > 2+ABOUT_SCREEN_W) continue;
- x = ((xx * star->x) >> 16) + ((yx * star->y) >> 16) + ((zx * star->z) >> 16);
- x = (int16_t)((((x >> 2) + x) << 7) / z) + (320-8);
- if ((uint16_t)x >= 640-16)
- continue;
-
// render star pixel if the pixel under it is the background
- screenBufferPos = ((y + 4) * SCREEN_W) + (x + 4);
+ screenBufferPos = ((uint32_t)y * SCREEN_W) + (uint32_t)x;
if ((video.frameBuffer[screenBufferPos] >> 24) == PAL_BCKGRND)
{
- col = ((uint8_t)~(z >> 8) >> 3) - (22 - 8);
+ col = ((uint8_t)~(z >> 8) >> 3) - 14;
if (col < 24)
{
video.frameBuffer[screenBufferPos] = video.palette[starColConv[col]] & 0x00FFFFFF;
--- a/src/ft2_audio.c
+++ b/src/ft2_audio.c
@@ -20,8 +20,8 @@
static int8_t pmpCountDiv, pmpChannels = 2;
static uint16_t smpBuffSize;
static int32_t masterVol, oldAudioFreq, speedVal, pmpLeft, randSeed = INITIAL_DITHER_SEED;
-static int32_t prngStateL, prngStateR;
-static uint32_t tickTimeLen, tickTimeLenFrac, oldSFrq, oldSFrqRev = 0xFFFFFFFF;
+static int32_t prngStateL, prngStateR, oldPeriod, oldSFrq, oldSFrqRev;
+static uint32_t tickTimeLen, tickTimeLenFrac;
static float fAudioAmpMul;
static voice_t voice[MAX_VOICES * 2];
static void (*sendAudSamplesFunc)(uint8_t *, uint32_t, uint8_t); // "send mixed samples" routines
@@ -31,8 +31,9 @@
volatile bool pattQueueReading, pattQueueClearing, chQueueReading, chQueueClearing;
-void resetOldRevFreqs(void)
+void resetCachedMixerVars(void)
{
+ oldPeriod = -1;
oldSFrq = 0;
oldSFrqRev = 0xFFFFFFFF;
}
@@ -369,11 +370,9 @@
// frequency change
if (status & IS_Period)
{
- v->SFrq = getFrequenceValue(ch->finalPeriod);
-
- if (v->SFrq != oldSFrq) // this value will very often be the same as before
+ if (ch->finalPeriod != oldPeriod) // this value will very often be the same as before
{
- oldSFrq = v->SFrq;
+ oldSFrq = getFrequenceValue(ch->finalPeriod);
oldSFrqRev = 0xFFFFFFFF;
if (oldSFrq != 0)
@@ -380,6 +379,7 @@
oldSFrqRev /= oldSFrq;
}
+ v->SFrq = oldSFrq;
v->SFrqRev = oldSFrqRev;
}
--- a/src/ft2_audio.h
+++ b/src/ft2_audio.h
@@ -45,8 +45,10 @@
bool backwards, isFadeOutVoice;
uint8_t SPan;
uint16_t SVol;
- int32_t SLVol1, SRVol1, SLVol2, SRVol2, SLVolIP, SRVolIP, SVolIPLen, SPos, SLen, SRepS, SRepL;
- uint32_t SPosDec, SFrq, SFrqRev;
+ int32_t SLVol1, SRVol1, SLVol2, SRVol2, SLVolIP, SRVolIP, SVolIPLen;
+ int32_t SPos, SLen, SRepS, SRepL, SFrq, SFrqRev;
+ uint32_t SPosDec;
+
void (*mixRoutine)(void *, int32_t); // function pointer to mix routine
} voice_t;
@@ -79,7 +81,7 @@
extern volatile bool pattQueueReading, pattQueueClearing, chQueueReading, chQueueClearing;
-void resetOldRevFreqs(void);
+void resetCachedMixerVars(void);
int32_t pattQueueReadSize(void);
int32_t pattQueueWriteSize(void);
bool pattQueuePush(pattSyncData_t t);
--- a/src/ft2_checkboxes.c
+++ b/src/ft2_checkboxes.c
@@ -79,7 +79,7 @@
// ------ CONFIG CHECKBOXES ------
//x, y, w, h, funcOnUp
- { 3, 91, 76, 12, cbToggleAutoSaveConfig },
+ { 3, 91, 77, 12, cbToggleAutoSaveConfig },
{ 389, 132, 90, 12, cbConfigInterpolation },
{ 389, 145, 107, 12, cbConfigVolRamp },
{ 389, 158 , 84, 12, cbConfigDither },
--- a/src/ft2_config.c
+++ b/src/ft2_config.c
@@ -1106,14 +1106,14 @@
showPushButton(PB_CONFIG_SAVE);
showPushButton(PB_CONFIG_EXIT);
- textOutShadow(5, 4, PAL_FORGRND, PAL_DSKTOP2, "Configuration:");
- textOutShadow(22, 20, PAL_FORGRND, PAL_DSKTOP2, "I/O devices");
- textOutShadow(22, 36, PAL_FORGRND, PAL_DSKTOP2, "Layout");
- textOutShadow(22, 52, PAL_FORGRND, PAL_DSKTOP2, "Miscellaneous");
+ textOutShadow(4, 4, PAL_FORGRND, PAL_DSKTOP2, "Configuration:");
+ textOutShadow(21, 19, PAL_FORGRND, PAL_DSKTOP2, "I/O devices");
+ textOutShadow(21, 35, PAL_FORGRND, PAL_DSKTOP2, "Layout");
+ textOutShadow(21, 51, PAL_FORGRND, PAL_DSKTOP2, "Miscellaneous");
#ifdef HAS_MIDI
- textOutShadow(22, 68, PAL_FORGRND, PAL_DSKTOP2, "MIDI input");
+ textOutShadow(21, 67, PAL_FORGRND, PAL_DSKTOP2, "MIDI input");
#endif
- textOutShadow(19, 92, PAL_FORGRND, PAL_DSKTOP2, "Auto save");
+ textOutShadow(20, 93, PAL_FORGRND, PAL_DSKTOP2, "Auto save");
switch (editor.currConfigScreen)
{
--- a/src/ft2_diskop.c
+++ b/src/ft2_diskop.c
@@ -104,7 +104,7 @@
if (stat(fileNameU, &st) != 0)
return 0;
- fSize = (int64_t)(st.st_size);
+ fSize = (int64_t)st.st_size;
#endif
if (fSize < 0)
fSize = 0;
--- a/src/ft2_header.h
+++ b/src/ft2_header.h
@@ -12,7 +12,7 @@
#endif
#include "ft2_replayer.h"
-#define PROG_VER_STR "1.14"
+#define PROG_VER_STR "1.15"
// do NOT change these! It will only mess things up...
--- a/src/ft2_help.c
+++ b/src/ft2_help.c
@@ -417,13 +417,13 @@
showScrollBar(SB_HELP_SCROLL);
- textOutShadow(4, 3, PAL_FORGRND, PAL_DSKTOP2, "Subjects:");
- textOutShadow(20, 17, PAL_FORGRND, PAL_DSKTOP2, "Features");
- textOutShadow(20, 32, PAL_FORGRND, PAL_DSKTOP2, "Effects");
- textOutShadow(20, 47, PAL_FORGRND, PAL_DSKTOP2, "Keyboard");
- textOutShadow(20, 62, PAL_FORGRND, PAL_DSKTOP2, "How to use FT2");
- textOutShadow(20, 77, PAL_FORGRND, PAL_DSKTOP2, "Problems/FAQ");
- textOutShadow(20, 92, PAL_FORGRND, PAL_DSKTOP2, "Known bugs");
+ textOutShadow(4, 4, PAL_FORGRND, PAL_DSKTOP2, "Subjects:");
+ textOutShadow(21, 19, PAL_FORGRND, PAL_DSKTOP2, "Features");
+ textOutShadow(21, 35, PAL_FORGRND, PAL_DSKTOP2, "Effects");
+ textOutShadow(21, 51, PAL_FORGRND, PAL_DSKTOP2, "Keyboard");
+ textOutShadow(21, 67, PAL_FORGRND, PAL_DSKTOP2, "How to use FT2");
+ textOutShadow(21, 83, PAL_FORGRND, PAL_DSKTOP2, "Problems/FAQ");
+ textOutShadow(21, 99, PAL_FORGRND, PAL_DSKTOP2, "Known bugs");
writeHelp();
}
--- a/src/ft2_inst_ed.c
+++ b/src/ft2_inst_ed.c
@@ -397,7 +397,7 @@
instrTyp *ins = getCurDispInstr();
sprintf(str, "%02d", ins->envVRepS);
- textOutFixed(382, 234, PAL_FORGRND, PAL_DESKTOP, str);
+ textOutFixed(382, 233, PAL_FORGRND, PAL_DESKTOP, str);
}
static void drawVolEnvRepE(void)
@@ -415,7 +415,7 @@
instrTyp *ins = getCurDispInstr();
sprintf(str, "%02d", ins->envPSust);
- textOutFixed(382, 294, PAL_FORGRND, PAL_DESKTOP, str);
+ textOutFixed(382, 293, PAL_FORGRND, PAL_DESKTOP, str);
}
static void drawPanEnvRepS(void)
@@ -424,7 +424,7 @@
instrTyp *ins = getCurDispInstr();
sprintf(str, "%02d", ins->envPRepS);
- textOutFixed(382, 321, PAL_FORGRND, PAL_DESKTOP, str);
+ textOutFixed(382, 320, PAL_FORGRND, PAL_DESKTOP, str);
}
static void drawPanEnvRepE(void)
@@ -433,7 +433,7 @@
instrTyp *ins = getCurDispInstr();
sprintf(str, "%02d", ins->envPRepE);
- textOutFixed(382, 335, PAL_FORGRND, PAL_DESKTOP, str);
+ textOutFixed(382, 334, PAL_FORGRND, PAL_DESKTOP, str);
}
static void drawVolume(void)
@@ -445,7 +445,7 @@
else
s = &instr[editor.curInstr]->samp[editor.curSmp];
- hexOutBg(505, 178, PAL_FORGRND, PAL_DESKTOP, s->vol, 2);
+ hexOutBg(505, 177, PAL_FORGRND, PAL_DESKTOP, s->vol, 2);
}
static void drawPanning(void)
@@ -457,7 +457,7 @@
else
s = &instr[editor.curInstr]->samp[editor.curSmp];
- hexOutBg(505, 192, PAL_FORGRND, PAL_DESKTOP, s->pan, 2);
+ hexOutBg(505, 191, PAL_FORGRND, PAL_DESKTOP, s->pan, 2);
}
static void drawFineTune(void)
@@ -2262,17 +2262,17 @@
textOutShadow(20, 176, PAL_FORGRND, PAL_DSKTOP2, "Volume envelope:");
textOutShadow(153, 176, PAL_FORGRND, PAL_DSKTOP2, "Predef.");
- textOutShadow(358, 193, PAL_FORGRND, PAL_DSKTOP2, "Sustain:");
+ textOutShadow(358, 194, PAL_FORGRND, PAL_DSKTOP2, "Sustain:");
textOutShadow(342, 206, PAL_FORGRND, PAL_DSKTOP2, "Point");
textOutShadow(358, 219, PAL_FORGRND, PAL_DSKTOP2, "Env.loop:");
- textOutShadow(342, 234, PAL_FORGRND, PAL_DSKTOP2, "Start");
+ textOutShadow(342, 233, PAL_FORGRND, PAL_DSKTOP2, "Start");
textOutShadow(342, 247, PAL_FORGRND, PAL_DSKTOP2, "End");
textOutShadow(20, 263, PAL_FORGRND, PAL_DSKTOP2, "Panning envelope:");
textOutShadow(152, 263, PAL_FORGRND, PAL_DSKTOP2, "Predef.");
- textOutShadow(358, 280, PAL_FORGRND, PAL_DSKTOP2, "Sustain:");
+ textOutShadow(358, 281, PAL_FORGRND, PAL_DSKTOP2, "Sustain:");
textOutShadow(342, 293, PAL_FORGRND, PAL_DSKTOP2, "Point");
textOutShadow(358, 306, PAL_FORGRND, PAL_DSKTOP2, "Env.loop:");
- textOutShadow(342, 321, PAL_FORGRND, PAL_DSKTOP2, "Start");
+ textOutShadow(342, 320, PAL_FORGRND, PAL_DSKTOP2, "Start");
textOutShadow(342, 334, PAL_FORGRND, PAL_DSKTOP2, "End");
textOutShadow(443, 177, PAL_FORGRND, PAL_DSKTOP2, "Volume");
textOutShadow(443, 191, PAL_FORGRND, PAL_DSKTOP2, "Panning");
@@ -2609,8 +2609,8 @@
textOutShadow(4, 96, PAL_FORGRND, PAL_DSKTOP2, "Instrument Editor Extension:");
textOutShadow(20, 114, PAL_FORGRND, PAL_DSKTOP2, "Instrument MIDI enable");
textOutShadow(189, 114, PAL_FORGRND, PAL_DSKTOP2, "Mute computer");
- textOutShadow(4, 133, PAL_FORGRND, PAL_DSKTOP2, "MIDI transmit channel");
- textOutShadow(4, 147, PAL_FORGRND, PAL_DSKTOP2, "MIDI program");
+ textOutShadow(4, 132, PAL_FORGRND, PAL_DSKTOP2, "MIDI transmit channel");
+ textOutShadow(4, 146, PAL_FORGRND, PAL_DSKTOP2, "MIDI program");
textOutShadow(4, 160, PAL_FORGRND, PAL_DSKTOP2, "Bender range (halftones)");
if (ins == NULL)
@@ -3268,9 +3268,9 @@
{
s->typ &= ~32;
- s->len /= 2;
- s->repL /= 2;
- s->repS /= 2;
+ s->len >>= 1;
+ s->repL >>= 1;
+ s->repS >>= 1;
newPtr = (int8_t *)realloc(s->origPek, s->len + LOOP_FIX_LEN);
if (newPtr != NULL)
@@ -3348,11 +3348,11 @@
{
ins->vibSweep = ih_PATWave.vibSweep;
- ins->vibRate = (ih_PATWave.vibRate + 2) / 4;
+ ins->vibRate = (ih_PATWave.vibRate + 2) >> 2;
if (ins->vibRate > 0x3F)
ins->vibRate = 0x3F;
- ins->vibDepth = (ih_PATWave.vibDepth + 1) / 2;
+ ins->vibDepth = (ih_PATWave.vibDepth + 1) >> 1;
if (ins->vibDepth > 0x0F)
ins->vibDepth = 0x0F;
}
--- a/src/ft2_mix.c
+++ b/src/ft2_mix.c
@@ -36,13 +36,10 @@
static void mix8bNoLoop(voice_t *v, uint32_t numSamples)
{
- const int8_t *CDA_LinearAdr;
- bool mixInMono;
- int32_t realPos, sample, *audioMixL, *audioMixR, CDA_BytesLeft;
- register const int8_t *smpPtr;
- register int32_t CDA_LVol, CDA_RVol;
- register uint32_t pos, delta;
- uint32_t i, samplesToMix;
+ const int8_t *CDA_LinearAdr, *smpPtr;
+ int32_t realPos, sample, *audioMixL, *audioMixR;
+ int32_t CDA_BytesLeft, CDA_LVol, CDA_RVol, i, samplesToMix;
+ uint32_t pos;
GET_VOL
@@ -103,13 +100,10 @@
static void mix8bLoop(voice_t *v, uint32_t numSamples)
{
- const int8_t *CDA_LinearAdr;
- bool mixInMono;
- int32_t realPos, sample, *audioMixL, *audioMixR, CDA_BytesLeft;
- register const int8_t *smpPtr;
- register int32_t CDA_LVol, CDA_RVol;
- register uint32_t pos, delta;
- uint32_t i, samplesToMix;
+ const int8_t *CDA_LinearAdr, *smpPtr;;
+ int32_t realPos, sample, *audioMixL, *audioMixR;
+ int32_t CDA_BytesLeft, CDA_LVol, CDA_RVol, i, samplesToMix;
+ uint32_t pos;
GET_VOL
@@ -170,13 +164,10 @@
static void mix8bBidiLoop(voice_t *v, uint32_t numSamples)
{
- bool mixInMono;
- const int8_t *CDA_LinearAdr, *CDA_LinAdrRev;
- int32_t realPos, sample, *audioMixL, *audioMixR, CDA_BytesLeft;
- register const int8_t *smpPtr;
- register int32_t CDA_LVol, CDA_RVol, CDA_IPValL, CDA_IPValH;
- register uint32_t pos;
- uint32_t delta, i, samplesToMix;
+ const int8_t *CDA_LinearAdr, *CDA_LinAdrRev, *smpPtr;
+ int32_t realPos, sample, *audioMixL, *audioMixR;
+ int32_t CDA_BytesLeft, CDA_LVol, CDA_RVol, i, samplesToMix;
+ uint32_t pos, delta;
GET_VOL
@@ -237,13 +228,10 @@
static void mix8bNoLoopIntrp(voice_t *v, uint32_t numSamples)
{
- const int8_t *CDA_LinearAdr;
- bool mixInMono;
- int32_t realPos, sample, sample2, *audioMixL, *audioMixR, CDA_BytesLeft;
- register const int8_t *smpPtr;
- register int32_t CDA_LVol, CDA_RVol;
- register uint32_t pos, delta;
- uint32_t i, samplesToMix;
+ const int8_t *CDA_LinearAdr, *smpPtr;
+ int32_t realPos, sample, sample2, *audioMixL, *audioMixR;
+ int32_t CDA_BytesLeft, CDA_LVol, CDA_RVol, i, samplesToMix;
+ uint32_t pos;
#ifndef LERPMIX
int32_t sample3, sample4;
#endif
@@ -307,13 +295,10 @@
static void mix8bLoopIntrp(voice_t *v, uint32_t numSamples)
{
- const int8_t *CDA_LinearAdr;
- bool mixInMono;
- int32_t realPos, sample, sample2, *audioMixL, *audioMixR, CDA_BytesLeft;
- register const int8_t *smpPtr;
- register int32_t CDA_LVol, CDA_RVol;
- register uint32_t pos, delta;
- uint32_t i, samplesToMix;
+ const int8_t *CDA_LinearAdr, *smpPtr;
+ int32_t realPos, sample, sample2, *audioMixL, *audioMixR;
+ int32_t CDA_BytesLeft, CDA_LVol, CDA_RVol, i, samplesToMix;
+ uint32_t pos;
#ifndef LERPMIX
int32_t sample3, sample4;
#endif
@@ -377,13 +362,10 @@
static void mix8bBidiLoopIntrp(voice_t *v, uint32_t numSamples)
{
- bool mixInMono;
- const int8_t *CDA_LinearAdr, *CDA_LinAdrRev;
- int32_t realPos, sample, sample2, *audioMixL, *audioMixR, CDA_BytesLeft;
- register const int8_t *smpPtr;
- register int32_t CDA_LVol, CDA_RVol, CDA_IPValL, CDA_IPValH;
- register uint32_t pos;
- uint32_t delta, i, samplesToMix;
+ const int8_t *CDA_LinearAdr, *CDA_LinAdrRev, *smpPtr;
+ int32_t realPos, sample, sample2, *audioMixL, *audioMixR;
+ int32_t CDA_BytesLeft, CDA_LVol, CDA_RVol, i, samplesToMix;
+ uint32_t pos, delta;
#ifndef LERPMIX
int32_t sample3, sample4;
#endif
@@ -448,13 +430,10 @@
static void mix8bRampNoLoop(voice_t *v, uint32_t numSamples)
{
- const int8_t *CDA_LinearAdr;
- bool mixInMono;
- int32_t realPos, sample, *audioMixL, *audioMixR, CDA_BytesLeft, CDA_LVolIP, CDA_RVolIP;
- register const int8_t *smpPtr;
- register int32_t CDA_LVol, CDA_RVol;
- register uint32_t pos, delta;
- uint32_t i, samplesToMix;
+ const int8_t *CDA_LinearAdr, *smpPtr;
+ int32_t realPos, sample, *audioMixL, *audioMixR, CDA_BytesLeft;
+ int32_t CDA_LVolIP, CDA_RVolIP, CDA_LVol, CDA_RVol, i, samplesToMix;
+ uint32_t pos;
if ((v->SLVol1 | v->SRVol1 | v->SLVol2 | v->SRVol2) == 0)
{
@@ -522,13 +501,10 @@
static void mix8bRampLoop(voice_t *v, uint32_t numSamples)
{
- const int8_t *CDA_LinearAdr;
- bool mixInMono;
- int32_t realPos, sample, *audioMixL, *audioMixR, CDA_BytesLeft, CDA_LVolIP, CDA_RVolIP;
- register const int8_t *smpPtr;
- register int32_t CDA_LVol, CDA_RVol;
- register uint32_t pos, delta;
- uint32_t i, samplesToMix;
+ const int8_t *CDA_LinearAdr, *smpPtr;;
+ int32_t realPos, sample, *audioMixL, *audioMixR, CDA_BytesLeft;
+ int32_t CDA_LVolIP, CDA_RVolIP, CDA_LVol, CDA_RVol, i, samplesToMix;
+ uint32_t pos;
if ((v->SLVol1 | v->SRVol1 | v->SLVol2 | v->SRVol2) == 0)
{
@@ -596,13 +572,10 @@
static void mix8bRampBidiLoop(voice_t *v, uint32_t numSamples)
{
- bool mixInMono;
- const int8_t *CDA_LinearAdr, *CDA_LinAdrRev;
- int32_t realPos, sample, *audioMixL, *audioMixR, CDA_BytesLeft, CDA_LVolIP, CDA_RVolIP;
- register const int8_t *smpPtr;
- register int32_t CDA_LVol, CDA_RVol, CDA_IPValL, CDA_IPValH;
- register uint32_t pos;
- uint32_t delta, i, samplesToMix;
+ const int8_t *CDA_LinearAdr, *CDA_LinAdrRev, *smpPtr;
+ int32_t realPos, sample, *audioMixL, *audioMixR, CDA_BytesLeft;
+ int32_t CDA_LVolIP, CDA_RVolIP, CDA_LVol, CDA_RVol, i, samplesToMix;
+ uint32_t pos, delta;
if ((v->SLVol1 | v->SRVol1 | v->SLVol2 | v->SRVol2) == 0)
{
@@ -671,13 +644,10 @@
static void mix8bRampNoLoopIntrp(voice_t *v, uint32_t numSamples)
{
- const int8_t *CDA_LinearAdr;
- bool mixInMono;
- int32_t realPos, sample, sample2, *audioMixL, *audioMixR, CDA_BytesLeft, CDA_LVolIP, CDA_RVolIP;
- register const int8_t *smpPtr;
- register int32_t CDA_LVol, CDA_RVol;
- register uint32_t pos, delta;
- uint32_t i, samplesToMix;
+ const int8_t *CDA_LinearAdr, *smpPtr;
+ int32_t realPos, sample, sample2, *audioMixL, *audioMixR, CDA_BytesLeft;
+ int32_t CDA_LVolIP, CDA_RVolIP, CDA_LVol, CDA_RVol, i, samplesToMix;
+ uint32_t pos;
#ifndef LERPMIX
int32_t sample3, sample4;
#endif
@@ -748,13 +718,10 @@
static void mix8bRampLoopIntrp(voice_t *v, uint32_t numSamples)
{
- const int8_t *CDA_LinearAdr;
- bool mixInMono;
- int32_t realPos, sample, sample2, *audioMixL, *audioMixR, CDA_BytesLeft, CDA_LVolIP, CDA_RVolIP;
- register const int8_t *smpPtr;
- register int32_t CDA_LVol, CDA_RVol;
- register uint32_t pos, delta;
- uint32_t i, samplesToMix;
+ const int8_t *CDA_LinearAdr, *smpPtr;
+ int32_t realPos, sample, sample2, *audioMixL, *audioMixR, CDA_BytesLeft;
+ int32_t CDA_LVolIP, CDA_RVolIP, CDA_LVol, CDA_RVol, i, samplesToMix;
+ uint32_t pos;
#ifndef LERPMIX
int32_t sample3, sample4;
#endif
@@ -825,13 +792,10 @@
static void mix8bRampBidiLoopIntrp(voice_t *v, uint32_t numSamples)
{
- bool mixInMono;
- const int8_t *CDA_LinearAdr, *CDA_LinAdrRev;
- int32_t realPos, sample, sample2, *audioMixL, *audioMixR, CDA_BytesLeft, CDA_LVolIP, CDA_RVolIP;
- register const int8_t *smpPtr;
- register int32_t CDA_LVol, CDA_RVol, CDA_IPValL, CDA_IPValH;
- register uint32_t pos;
- uint32_t delta, i, samplesToMix;
+ const int8_t *CDA_LinearAdr, *CDA_LinAdrRev, *smpPtr;
+ int32_t realPos, sample, sample2, *audioMixL, *audioMixR, CDA_BytesLeft;
+ int32_t CDA_LVolIP, CDA_RVolIP, CDA_LVol, CDA_RVol, i, samplesToMix;
+ uint32_t pos, delta;
#ifndef LERPMIX
int32_t sample3, sample4;
#endif
@@ -908,13 +872,10 @@
static void mix16bNoLoop(voice_t *v, uint32_t numSamples)
{
- bool mixInMono;
- const int16_t *CDA_LinearAdr;
- int32_t realPos, sample, *audioMixL, *audioMixR, CDA_BytesLeft;
- register const int16_t *smpPtr;
- register int32_t CDA_LVol, CDA_RVol;
- register uint32_t pos, delta;
- uint32_t i, samplesToMix;
+ const int16_t *CDA_LinearAdr, *smpPtr;
+ int32_t realPos, sample, *audioMixL, *audioMixR;
+ int32_t CDA_BytesLeft, CDA_LVol, CDA_RVol, i, samplesToMix;
+ uint32_t pos;
GET_VOL
@@ -975,13 +936,10 @@
static void mix16bLoop(voice_t *v, uint32_t numSamples)
{
- bool mixInMono;
- const int16_t *CDA_LinearAdr;
- int32_t realPos, sample, *audioMixL, *audioMixR, CDA_BytesLeft;
- register const int16_t *smpPtr;
- register int32_t CDA_LVol, CDA_RVol;
- register uint32_t pos, delta;
- uint32_t i, samplesToMix;
+ const int16_t *CDA_LinearAdr, *smpPtr;
+ int32_t realPos, sample, *audioMixL, *audioMixR;
+ int32_t CDA_BytesLeft, CDA_LVol, CDA_RVol, i, samplesToMix;
+ uint32_t pos;
GET_VOL
@@ -1042,13 +1000,10 @@
static void mix16bBidiLoop(voice_t *v, uint32_t numSamples)
{
- bool mixInMono;
- const int16_t *CDA_LinearAdr, *CDA_LinAdrRev;
- int32_t realPos, sample, *audioMixL, *audioMixR, CDA_BytesLeft;
- register const int16_t *smpPtr;
- register int32_t CDA_LVol, CDA_RVol, CDA_IPValL, CDA_IPValH;
- register uint32_t pos;
- uint32_t delta, i, samplesToMix;
+ const int16_t *CDA_LinearAdr, *CDA_LinAdrRev, *smpPtr;
+ int32_t realPos, sample, *audioMixL, *audioMixR;
+ int32_t CDA_BytesLeft, CDA_LVol, CDA_RVol, i, samplesToMix;
+ uint32_t pos, delta;
GET_VOL
@@ -1110,13 +1065,10 @@
static void mix16bNoLoopIntrp(voice_t *v, uint32_t numSamples)
{
- bool mixInMono;
- const int16_t *CDA_LinearAdr;
- int32_t realPos, sample, sample2, *audioMixL, *audioMixR, CDA_BytesLeft;
- register const int16_t *smpPtr;
- register int32_t CDA_LVol, CDA_RVol;
- register uint32_t pos, delta;
- uint32_t i, samplesToMix;
+ const int16_t *CDA_LinearAdr, *smpPtr;
+ int32_t realPos, sample, sample2, *audioMixL, *audioMixR;
+ int32_t CDA_BytesLeft, CDA_LVol, CDA_RVol, i, samplesToMix;
+ uint32_t pos;
#ifndef LERPMIX
int32_t sample3, sample4;
#endif
@@ -1180,13 +1132,10 @@
static void mix16bLoopIntrp(voice_t *v, uint32_t numSamples)
{
- bool mixInMono;
- const int16_t *CDA_LinearAdr;
- int32_t realPos, sample, sample2, *audioMixL, *audioMixR, CDA_BytesLeft;
- register const int16_t *smpPtr;
- register int32_t CDA_LVol, CDA_RVol;
- register uint32_t pos, delta;
- uint32_t i, samplesToMix;
+ const int16_t *CDA_LinearAdr, *smpPtr;
+ int32_t realPos, sample, sample2, *audioMixL, *audioMixR;
+ int32_t CDA_BytesLeft, CDA_LVol, CDA_RVol, i, samplesToMix;
+ uint32_t pos;
#ifndef LERPMIX
int32_t sample3, sample4;
#endif
@@ -1250,13 +1199,10 @@
static void mix16bBidiLoopIntrp(voice_t *v, uint32_t numSamples)
{
- bool mixInMono;
- const int16_t *CDA_LinearAdr, *CDA_LinAdrRev;
- int32_t realPos, sample, sample2, *audioMixL, *audioMixR, CDA_BytesLeft;
- register const int16_t *smpPtr;
- register int32_t CDA_LVol, CDA_RVol, CDA_IPValL, CDA_IPValH;
- register uint32_t pos;
- uint32_t delta, i, samplesToMix;
+ const int16_t *CDA_LinearAdr, *CDA_LinAdrRev, *smpPtr;
+ int32_t realPos, sample, sample2, *audioMixL, *audioMixR;
+ int32_t CDA_BytesLeft, CDA_LVol, CDA_RVol, i, samplesToMix;
+ uint32_t pos, delta;
#ifndef LERPMIX
int32_t sample3, sample4;
#endif
@@ -1321,13 +1267,10 @@
static void mix16bRampNoLoop(voice_t *v, uint32_t numSamples)
{
- bool mixInMono;
- const int16_t *CDA_LinearAdr;
- int32_t realPos, sample, *audioMixL, *audioMixR, CDA_BytesLeft, CDA_LVolIP, CDA_RVolIP;
- register const int16_t *smpPtr;
- register int32_t CDA_LVol, CDA_RVol;
- register uint32_t pos, delta;
- uint32_t i, samplesToMix;
+ const int16_t *CDA_LinearAdr, *smpPtr;
+ int32_t realPos, sample, *audioMixL, *audioMixR, CDA_BytesLeft;
+ int32_t CDA_LVolIP, CDA_RVolIP, CDA_LVol, CDA_RVol, i, samplesToMix;
+ uint32_t pos;
if ((v->SLVol1 | v->SRVol1 | v->SLVol2 | v->SRVol2) == 0)
{
@@ -1395,13 +1338,10 @@
static void mix16bRampLoop(voice_t *v, uint32_t numSamples)
{
- bool mixInMono;
- const int16_t *CDA_LinearAdr;
- int32_t realPos, sample, *audioMixL, *audioMixR, CDA_BytesLeft, CDA_LVolIP, CDA_RVolIP;
- register const int16_t *smpPtr;
- register int32_t CDA_LVol, CDA_RVol;
- register uint32_t pos, delta;
- uint32_t i, samplesToMix;
+ const int16_t *CDA_LinearAdr, *smpPtr;
+ int32_t realPos, sample, *audioMixL, *audioMixR, CDA_BytesLeft;
+ int32_t CDA_LVolIP, CDA_RVolIP, CDA_LVol, CDA_RVol, i, samplesToMix;
+ uint32_t pos;
if ((v->SLVol1 | v->SRVol1 | v->SLVol2 | v->SRVol2) == 0)
{
@@ -1469,13 +1409,10 @@
static void mix16bRampBidiLoop(voice_t *v, uint32_t numSamples)
{
- bool mixInMono;
- const int16_t *CDA_LinearAdr, *CDA_LinAdrRev;
- int32_t realPos, sample, *audioMixL, *audioMixR, CDA_BytesLeft, CDA_LVolIP, CDA_RVolIP;
- register const int16_t *smpPtr;
- register int32_t CDA_LVol, CDA_RVol, CDA_IPValL, CDA_IPValH;
- register uint32_t pos;
- uint32_t delta, i, samplesToMix;
+ const int16_t *CDA_LinearAdr, *CDA_LinAdrRev, *smpPtr;
+ int32_t realPos, sample, *audioMixL, *audioMixR, CDA_BytesLeft;
+ int32_t CDA_LVolIP, CDA_RVolIP, CDA_LVol, CDA_RVol, i, samplesToMix;
+ uint32_t pos, delta;
if ((v->SLVol1 | v->SRVol1 | v->SLVol2 | v->SRVol2) == 0)
{
@@ -1544,13 +1481,10 @@
static void mix16bRampNoLoopIntrp(voice_t *v, uint32_t numSamples)
{
- bool mixInMono;
- const int16_t *CDA_LinearAdr;
- int32_t realPos, sample, sample2, *audioMixL, *audioMixR, CDA_BytesLeft, CDA_LVolIP, CDA_RVolIP;
- register const int16_t *smpPtr;
- register int32_t CDA_LVol, CDA_RVol;
- register uint32_t pos, delta;
- uint32_t i, samplesToMix;
+ const int16_t *CDA_LinearAdr, *smpPtr;
+ int32_t realPos, sample, sample2, *audioMixL, *audioMixR, CDA_BytesLeft;
+ int32_t CDA_LVolIP, CDA_RVolIP, CDA_LVol, CDA_RVol, i, samplesToMix;
+ uint32_t pos;
#ifndef LERPMIX
int32_t sample3, sample4;
#endif
@@ -1621,13 +1555,10 @@
static void mix16bRampLoopIntrp(voice_t *v, uint32_t numSamples)
{
- bool mixInMono;
- const int16_t *CDA_LinearAdr;
- int32_t realPos, sample, sample2, *audioMixL, *audioMixR, CDA_BytesLeft, CDA_LVolIP, CDA_RVolIP;
- register const int16_t *smpPtr;
- register int32_t CDA_LVol, CDA_RVol;
- register uint32_t pos, delta;
- uint32_t i, samplesToMix;
+ const int16_t *CDA_LinearAdr, *smpPtr;
+ int32_t realPos, sample, sample2, *audioMixL, *audioMixR, CDA_BytesLeft;
+ int32_t CDA_LVolIP, CDA_RVolIP, CDA_LVol, CDA_RVol, i, samplesToMix;
+ uint32_t pos;
#ifndef LERPMIX
int32_t sample3, sample4;
#endif
@@ -1698,13 +1629,10 @@
static void mix16bRampBidiLoopIntrp(voice_t *v, uint32_t numSamples)
{
- bool mixInMono;
- const int16_t *CDA_LinearAdr, *CDA_LinAdrRev;
- int32_t realPos, sample, sample2, *audioMixL, *audioMixR, CDA_BytesLeft, CDA_LVolIP, CDA_RVolIP;
- register const int16_t *smpPtr;
- register int32_t CDA_LVol, CDA_RVol, CDA_IPValL, CDA_IPValH;
- register uint32_t pos;
- uint32_t delta, i, samplesToMix;
+ const int16_t *CDA_LinearAdr, *CDA_LinAdrRev, *smpPtr;
+ int32_t realPos, sample, sample2, *audioMixL, *audioMixR, CDA_BytesLeft;
+ int32_t CDA_LVolIP, CDA_RVolIP, CDA_LVol, CDA_RVol, i, samplesToMix;
+ uint32_t pos, delta;
#ifndef LERPMIX
int32_t sample3, sample4;
#endif
--- a/src/ft2_mix_macros.h
+++ b/src/ft2_mix_macros.h
@@ -14,21 +14,24 @@
v->SLVol2 = CDA_LVol; \
v->SRVol2 = CDA_RVol; \
-#define GET_DELTA delta = v->SFrq;
+#define GET_DELTA \
+ const uint32_t delta = v->SFrq;
#define GET_MIXER_VARS \
+ const int32_t SFrqRev = v->SFrqRev; \
audioMixL = audio.mixBufferL; \
audioMixR = audio.mixBufferR; \
- mixInMono = (CDA_LVol == CDA_RVol); \
+ const bool mixInMono = (CDA_LVol == CDA_RVol); \
realPos = v->SPos; \
pos = v->SPosDec; \
#define GET_MIXER_VARS_RAMP \
+ const int32_t SFrqRev = v->SFrqRev; \
audioMixL = audio.mixBufferL; \
audioMixR = audio.mixBufferR; \
CDA_LVolIP = v->SLVolIP; \
CDA_RVolIP = v->SRVolIP; \
- mixInMono = (v->SLVol2 == v->SRVol2) && (CDA_LVolIP == CDA_RVolIP); \
+ const bool mixInMono = (v->SLVol2 == v->SRVol2) && (CDA_LVolIP == CDA_RVolIP); \
realPos = v->SPos; \
pos = v->SPosDec; \
@@ -240,12 +243,15 @@
/* ----------------------------------------------------------------------- */
#define LIMIT_MIX_NUM \
- i = (v->SLen - 1) - realPos; \
- if (i > 65535) \
- i = 65535; \
+ samplesToMix = (v->SLen - 1) - realPos; \
+ if (samplesToMix > 65535) \
+ samplesToMix = 65535; \
\
- samplesToMix = (((((uint64_t)i << 16) | (pos ^ 0xFFFF)) * v->SFrqRev) >> 32) + 1; \
- if (samplesToMix > (uint32_t)CDA_BytesLeft) \
+ samplesToMix = (samplesToMix << 16) | (pos ^ 0xFFFF); \
+ samplesToMix = ((int64_t)samplesToMix * SFrqRev) >> 32; \
+ samplesToMix++; \
+ \
+ if (samplesToMix > CDA_BytesLeft) \
samplesToMix = CDA_BytesLeft; \
#define LIMIT_MIX_NUM_RAMP \
@@ -262,7 +268,7 @@
} \
else \
{ \
- if (samplesToMix > (uint32_t)v->SVolIPLen) \
+ if (samplesToMix > v->SVolIPLen) \
samplesToMix = v->SVolIPLen; \
\
v->SVolIPLen -= samplesToMix; \
@@ -272,7 +278,6 @@
if (v->backwards) \
{ \
delta = 0 - v->SFrq; \
- CDA_IPValH = (int32_t)delta >> 16; \
assert(realPos >= v->SRepS && realPos < v->SLen); \
realPos = ~realPos; \
smpPtr = CDA_LinAdrRev + realPos; \
@@ -281,19 +286,18 @@
else \
{ \
delta = v->SFrq; \
- CDA_IPValH = delta >> 16; \
assert(realPos >= 0 && realPos < v->SLen); \
smpPtr = CDA_LinearAdr + realPos; \
} \
\
- CDA_IPValL = delta & 0xFFFF; \
+ const int32_t CDA_IPValH = (int32_t)delta >> 16; \
+ const int32_t CDA_IPValL = delta & 0xFFFF; \
#define END_BIDI \
if (v->backwards) \
{ \
pos ^= 0xFFFF; \
- realPos = (int32_t)(smpPtr - CDA_LinAdrRev); \
- realPos = ~realPos; \
+ realPos = ~(int32_t)(smpPtr - CDA_LinAdrRev); \
} \
else \
{ \
--- a/src/ft2_module_loader.c
+++ b/src/ft2_module_loader.c
@@ -184,7 +184,7 @@
if (IS_ID("M.K.", id) || IS_ID("M!K!", id) || IS_ID("NSMS", id) || IS_ID("LARD", id) || IS_ID("PATT", id))
{
- modFormat = FORMAT_MK; // ProTracker or compatible
+ modFormat = FORMAT_MK; // ProTracker or compatible
}
else if (id[1] == 'C' && id[2] == 'H' && id[3] == 'N')
{
@@ -200,11 +200,6 @@
{
modFormat = FORMAT_FLT; // StarTrekker (4-channel modules only)
}
- else if (IS_ID("FLT8", id))
- {
- modFormat = FORMAT_FLT; // StarTrekker (4-channel modules only)
- *numChannels = 8;
- }
else if (IS_ID("N.T.", id))
{
modFormat = FORMAT_NT; // NoiseTracker
@@ -364,23 +359,23 @@
*/
modFormat = FORMAT_STK;
- if (h_MOD15.repS == 0)
- h_MOD15.repS = 120;
+ if (songTmp.repS == 0)
+ songTmp.repS = 120;
- // jjk55.mod by Jesper Kyd has a bogus STK tempo value that should be ignored
+ // jjk55.mod by Jesper Kyd has a bogus STK tempo value that should be ignored (hackish!)
if (!strcmp("jjk55", h_MOD31.name))
- h_MOD15.repS = 120;
+ songTmp.repS = 120;
// The "restart pos" field in STK is the inital tempo (must be converted to BPM first)
- if (h_MOD15.repS != 120) // 120 is a special case and means 50Hz (125BPM)
+ if (songTmp.repS != 120) // 120 is a special case and means 50Hz (125BPM)
{
- if (h_MOD15.repS > 220)
- h_MOD15.repS = 220;
+ if (songTmp.repS > 220)
+ songTmp.repS = 220;
// convert UST tempo to BPM
uint16_t ciaPeriod = (240 - songTmp.repS) * 122;
double dHz = 709379.0 / ciaPeriod;
- int32_t BPM = (int32_t)((dHz * (125.0 / 50.0)) + 0.5);
+ int32_t BPM = (int32_t)((dHz * 2.5) + 0.5);
songTmp.speed = (uint16_t)BPM;
}
@@ -450,7 +445,7 @@
ton->effTyp = bytes[2] & 0x0F;
ton->eff = bytes[3];
- if (mightBeSTK)
+ if (modFormat == FORMAT_STK)
{
if (ton->effTyp == 0xC || ton->effTyp == 0xD || ton->effTyp == 0xE)
{
@@ -519,7 +514,7 @@
}
// pattern command conversion for non-PT formats
- if (modFormat == FORMAT_STK || modFormat == FORMAT_FT2 || modFormat == FORMAT_NT || modFormat == FORMAT_HMNT || modFormat == FORMAT_FLT)
+ if (modFormat == FORMAT_STK || modFormat == FORMAT_NT || modFormat == FORMAT_HMNT || modFormat == FORMAT_FLT)
{
for (a = 0; a < b; a++)
{
@@ -690,7 +685,7 @@
/* For Ultimate SoundTracker modules, only the loop area of a looped sample is played.
** Skip loading of eventual data present before loop start.
*/
- if (modFormat == FORMAT_STK && (s->repS > 0 && s->repL < s->len))
+ if (modFormat == FORMAT_STK && s->repS > 0 && s->repL < s->len)
{
s->len -= s->repS;
fseek(f, s->repS, SEEK_CUR);
@@ -705,7 +700,7 @@
}
// clear repL and repS on non-looping samples...
- if ((s->typ & 3) == 0)
+ if (s->typ == 0)
{
s->repL = 0;
s->repS = 0;
@@ -735,18 +730,15 @@
uint16_t hz = 50;
hz -= ((slowdowns[tempo >> 4] * (tempo & 15)) >> 4); // can and will underflow
-
- bpm = (int32_t)((hz * 2.5) + 0.5);
+ bpm = (hz << 1) + (hz >> 1); // BPM = hz * 2.5
return (uint8_t)CLAMP(bpm, 32, 255); // result can be slightly off, but close enough...
}
static bool loadMusicSTM(FILE *f, uint32_t fileLength, bool fromExternalThread)
{
- bool check3xx;
- uint8_t typ, tmp8, tempo;
+ uint8_t typ, tempo;
int16_t i, j, k, ai, ap, tmp;
uint16_t a;
- int32_t len;
tonTyp *ton;
sampleTyp *s;
songSTMHeaderTyp h_STM;
@@ -887,19 +879,6 @@
ton->eff = 0;
}
- /* Remove any EDx with no note.
- ** SDx with no note in ST3 = does nothing
- ** EDx with no note in FT2 = still retriggers
- */
- if (ton->effTyp == 0xE && (ton->eff & 0xF0) == 0xD0)
- {
- if (ton->ton == 0 || ton->ton == 97)
- {
- ton->eff = 0;
- ton->effTyp = 0;
- }
- }
-
if (ton->effTyp > 35)
{
ton->effTyp = 0;
@@ -986,77 +965,6 @@
}
}
- // non-FT2: fix overflown 9xx and illegal 3xx
-
- for (i = 0; i < ap; i++)
- {
- if (pattTmp[i] == NULL)
- continue;
-
- for (k = 0; k < songTmp.antChn; k++)
- {
- check3xx = false;
- for (j = 0; j < 64; j++)
- {
- ton = &pattTmp[i][(j * MAX_VOICES) + k];
-
- if (ton->ton > 0 && ton->ton < 97 && ton->effTyp != 0x3)
- check3xx = true;
-
- if (ton->ton > 0 && ton->ton < 97 && ton->effTyp == 0x3)
- check3xx = false;
-
- if (check3xx && ton->effTyp == 0x3)
- {
- if (ton->ton == 0 || ton->ton == 97)
- {
- ton->effTyp = 0;
- ton->eff = 0;
- }
- }
-
- if (ton->effTyp == 0x9 && ton->eff > 0)
- {
- if (ton->instr != 0 && ton->instr <= ai)
- {
- s = &instrTmp[ton->instr]->samp[0];
- len = s->len;
-
- tmp8 = 0;
- if (len > 0)
- {
- tmp8 = ton->eff;
-
- int32_t newLen = len >> 8;
- if (tmp8 >= newLen)
- {
- if (newLen < 1)
- tmp8 = 0;
- else
- tmp8 = (uint8_t)(newLen - 1);
- }
- }
-
- if (tmp8 > 0)
- {
- ton->eff = tmp8;
- }
- else
- {
- ton->effTyp = 0;
- ton->eff = 0;
- }
- }
- else
- {
- ton->effTyp = 0;
- ton->eff = 0;
- }
- }
- }
- }
- }
-
fclose(f);
moduleLoaded = true;
@@ -1102,14 +1010,14 @@
static bool loadMusicS3M(FILE *f, uint32_t dataLength, bool fromExternalThread)
{
int8_t *tmpSmp;
- bool check3xx, illegalUxx;
+ bool illegalUxx;
uint8_t ha[2048];
- uint8_t s3mLastDEff[32], s3mLastEEff[32], s3mLastFEff[32];
- uint8_t s3mLastSEff[32], s3mLastJEff[32], s3mLastGInstr[32], typ;
+ uint8_t alastnfo[32], alastefx[32], alastvibnfo[32], s3mLastGInstr[32];
+ uint8_t typ;
int16_t ai, ap, ver, ii, kk, tmp;
uint16_t ptnOfs[256];
int32_t i, j, k, len;
- tonTyp ton, *pattTon;
+ tonTyp ton;
sampleTyp *s;
songS3MHeaderTyp h_S3M;
songS3MinstrHeaderTyp h_S3MInstr;
@@ -1143,14 +1051,8 @@
goto s3mLoadError;
}
- // count real song table entries
- songTmp.len = 256;
- while (songTmp.len > 0 && songTmp.songTab[songTmp.len-1] == 255)
- songTmp.len--;
+ songTmp.len = h_S3M.songTabLen;
- if (songTmp.len == 256)
- songTmp.len = 255;
-
// remove pattern separators (254)
k = 0;
j = 0;
@@ -1165,11 +1067,20 @@
if (k <= songTmp.len)
songTmp.len -= (uint16_t)k;
else
- songTmp.len = 0;
+ songTmp.len = 1;
+
+ for (i = 1; i < songTmp.len; i++)
+ {
+ if (songTmp.songTab[i] == 255)
+ {
+ songTmp.len = (uint16_t)i;
+ break;
+ }
+ }
// clear unused song table entries
if (songTmp.len < 255)
- memset(&songTmp.songTab[songTmp.len], 0, 256 - songTmp.len);
+ memset(&songTmp.songTab[songTmp.len], 0, 255-songTmp.len);
songTmp.speed = h_S3M.defTempo;
if (songTmp.speed < 32)
@@ -1226,11 +1137,9 @@
if (ptnOfs[i] == 0)
continue; // empty pattern
- memset(s3mLastDEff, 0, sizeof (s3mLastDEff));
- memset(s3mLastEEff, 0, sizeof (s3mLastEEff));
- memset(s3mLastFEff, 0, sizeof (s3mLastFEff));
- memset(s3mLastSEff, 0, sizeof (s3mLastSEff));
- memset(s3mLastJEff, 0, sizeof (s3mLastJEff));
+ memset(alastnfo, 0, sizeof (alastnfo));
+ memset(alastefx, 0, sizeof (alastefx));
+ memset(alastvibnfo, 0, sizeof (alastvibnfo));
memset(s3mLastGInstr, 0, sizeof (s3mLastGInstr));
fseek(f, ptnOfs[i] << 4, SEEK_SET);
@@ -1295,7 +1204,7 @@
}
}
- // volume
+ // volume column
if (typ & 64)
{
ton.vol = pattBuff[k++];
@@ -1312,28 +1221,42 @@
ton.effTyp = pattBuff[k++];
ton.eff = pattBuff[k++];
- if (ton.eff == 0)
+ if (ton.eff > 0)
{
- if (ton.effTyp == 4)
+ alastnfo[ii] = ton.eff;
+ if (ton.effTyp == 8 || ton.effTyp == 21)
+ alastvibnfo[ii] = ton.eff; // H/U
+ }
+
+ // in ST3, a lot of effects directly share the same memory!
+ if (ton.eff == 0 && ton.effTyp != 7) // G
+ {
+ uint8_t efx = ton.effTyp;
+ if (efx == 8 || efx == 21) // H/U
+ ton.eff = alastvibnfo[ii];
+ else if ((efx >= 4 && efx <= 12) || (efx >= 17 && efx <= 19)) // D/E/F/I/J/K/L/Q/R/S
+ ton.eff = alastnfo[ii];
+
+ /* If effect data is zero and effect type was the same as last one, clear out
+ ** data if it's not J or S (those have no memory in the equivalent XM effects).
+ ** Also goes for extra fine pitch slides and fine volume slides,
+ ** since they get converted to other effects.
+ */
+ if (efx == alastefx[ii] && ton.effTyp != 10 && ton.effTyp != 19) // J/S
{
- if ((s3mLastDEff[ii] & 0xF0) == 0xF0 || (s3mLastDEff[ii] & 0x0F) == 0x0F)
- ton.eff = s3mLastDEff[ii];
+ uint8_t nfo = ton.eff;
+ bool extraFinePitchSlides = (efx == 5 || efx == 6) && ((nfo & 0xF0) == 0xE0);
+ bool fineVolSlides = (efx == 4 || efx == 11) &&
+ ((nfo > 0xF0) || (((nfo & 0xF) == 0xF) && ((nfo & 0xF0) > 0)));
+
+ if (!extraFinePitchSlides && !fineVolSlides)
+ ton.eff = 0;
}
- else if (ton.effTyp == 5) ton.eff = s3mLastEEff[ii];
- else if (ton.effTyp == 6) ton.eff = s3mLastFEff[ii];
- else if (ton.effTyp == 10) ton.eff = s3mLastJEff[ii];
- else if (ton.effTyp == 19) ton.eff = s3mLastSEff[ii];
}
-
- if (ton.eff != 0)
- {
- if (ton.effTyp == 4) s3mLastDEff[ii] = ton.eff;
- else if (ton.effTyp == 5) s3mLastEEff[ii] = ton.eff;
- else if (ton.effTyp == 6) s3mLastFEff[ii] = ton.eff;
- else if (ton.effTyp == 10) s3mLastJEff[ii] = ton.eff;
- else if (ton.effTyp == 19) s3mLastSEff[ii] = ton.eff;
- }
+ if (ton.effTyp > 0)
+ alastefx[ii] = ton.effTyp;
+
switch (ton.effTyp)
{
case 1: // A
@@ -1351,14 +1274,12 @@
case 3: ton.effTyp = 0xD; break; // C
case 4: // D
{
- if ((ton.eff & 0xF0) == 0) ton.effTyp = 0xA;
- else if ((ton.eff & 0x0F) == 0) ton.effTyp = 0xA;
- else if ((ton.eff & 0xF0) == 0xF0)
+ if (ton.eff > 0xF0) // fine slide up
{
ton.effTyp = 0xE;
- ton.eff = 0xB0 | (ton.eff & 15);
+ ton.eff = 0xB0 | (ton.eff & 0xF);
}
- else if ((ton.eff & 0x0F) == 0x0F)
+ else if ((ton.eff & 0x0F) == 0x0F && (ton.eff & 0xF0) > 0) // fine slide down
{
ton.effTyp = 0xE;
ton.eff = 0xA0 | (ton.eff >> 4);
@@ -1366,10 +1287,8 @@
else
{
ton.effTyp = 0xA;
- if (ton.eff & 0x0F)
+ if (ton.eff & 0x0F) // on D/K, last nybble has first priority in ST3
ton.eff &= 0x0F;
- else
- ton.eff &= 0xF0;
}
}
break;
@@ -1379,6 +1298,7 @@
{
if ((ton.eff & 0xF0) >= 0xE0)
{
+ // convert to fine slide
if ((ton.eff & 0xF0) == 0xE0)
tmp = 0x21;
else
@@ -1392,9 +1312,15 @@
ton.eff |= 0x10;
ton.effTyp = (uint8_t)tmp;
+
+ if (ton.effTyp == 0x21 && ton.eff == 0)
+ {
+ ton.effTyp = 0;
+ }
}
else
{
+ // convert to normal 1xx/2xx slide
ton.effTyp = 7 - ton.effTyp;
}
}
@@ -1402,11 +1328,40 @@
case 7: // G
{
+ ton.effTyp = 0x03;
+
// fix illegal slides (to new instruments)
if (ton.instr != 0 && ton.instr != s3mLastGInstr[ii])
ton.instr = s3mLastGInstr[ii];
+ }
+ break;
- ton.effTyp = 0x03;
+ case 11: // K
+ {
+ if (ton.eff > 0xF0) // fine slide up
+ {
+ ton.effTyp = 0xE;
+ ton.eff = 0xB0 | (ton.eff & 0xF);
+
+ // if volume column is unoccupied, set to vibrato
+ if (ton.vol == 0)
+ ton.vol = 0xB0;
+ }
+ else if ((ton.eff & 0x0F) == 0x0F && (ton.eff & 0xF0) > 0) // fine slide down
+ {
+ ton.effTyp = 0xE;
+ ton.eff = 0xA0 | (ton.eff >> 4);
+
+ // if volume column is unoccupied, set to vibrato
+ if (ton.vol == 0)
+ ton.vol = 0xB0;
+ }
+ else
+ {
+ ton.effTyp = 0x6;
+ if (ton.eff & 0x0F) // on D/K, last nybble has first priority in ST3
+ ton.eff &= 0x0F;
+ }
}
break;
@@ -1413,7 +1368,6 @@
case 8: ton.effTyp = 0x04; break; // H
case 9: ton.effTyp = 0x1D; break; // I
case 10: ton.effTyp = 0x00; break; // J
- case 11: ton.effTyp = 0x06; break; // K
case 12: ton.effTyp = 0x05; break; // L
case 15: ton.effTyp = 0x09; break; // O
case 17: ton.effTyp = 0x1B; break; // Q
@@ -1429,10 +1383,37 @@
else if (tmp == 0x2) ton.eff |= 0x50;
else if (tmp == 0x3) ton.eff |= 0x40;
else if (tmp == 0x4) ton.eff |= 0x70;
- // we ignore S8x (set 4-bit pan) becuase it's not compatible with FT2 panning
+ // ignore S8x becuase it's not compatible with FT2 panning
else if (tmp == 0xB) ton.eff |= 0x60;
- else if (tmp == 0xC) ton.eff |= 0xC0;
- else if (tmp == 0xD) ton.eff |= 0xD0;
+ else if (tmp == 0xC) // Note Cut
+ {
+ ton.eff |= 0xC0;
+ if (ton.eff == 0xC0)
+ {
+ // EC0 does nothing in ST3 but cuts voice in FT2, remove effect
+ ton.effTyp = 0;
+ ton.eff = 0;
+ }
+ }
+ else if (tmp == 0xD) // Note Delay
+ {
+ ton.eff |= 0xD0;
+ if (ton.ton == 0 || ton.ton == 97)
+ {
+ // EDx without a note does nothing in ST3 but retrigs in FT2, remove effect
+ ton.effTyp = 0;
+ ton.eff = 0;
+ }
+ else if (ton.eff == 0xD0)
+ {
+ // ED0 prevents note/smp/vol from updating in ST3, remove everything
+ ton.ton = 0;
+ ton.instr = 0;
+ ton.vol = 0;
+ ton.effTyp = 0;
+ ton.eff = 0;
+ }
+ }
else if (tmp == 0xE) ton.eff |= 0xE0;
else if (tmp == 0xF) ton.eff |= 0xF0;
else
@@ -1454,40 +1435,18 @@
}
break;
- case 21: // U (fine vibrato, doesn't exist in FT2, do a poor conversion to normal vibrato)
+ case 22: // V
{
- if ((ton.eff & 0x0F) != 0)
+ ton.effTyp = 0x10;
+ if (ton.eff > 0x40)
{
- ton.eff = (ton.eff & 0xF0) | (((ton.eff & 15) + 1) >> 2); // divide depth by 4
- if ((ton.eff & 0x0F) == 0) // depth too low, remove effect
- {
- illegalUxx = true;
- ton.effTyp = 0;
- ton.eff = 0;
- }
- else
- {
- illegalUxx = false;
- ton.effTyp = 0x04;
- }
+ // Vxx > 0x40 does nothing in ST3
+ ton.effTyp = 0;
+ ton.eff = 0;
}
- else
- {
- if (!illegalUxx)
- {
- ton.effTyp = 0x04;
- }
- else
- {
- ton.effTyp = 0;
- ton.eff = 0;
- }
- }
}
break;
- case 22: ton.effTyp = 0x10; break; // V
-
default:
{
ton.effTyp = 0;
@@ -1500,40 +1459,6 @@
if (ton.instr != 0 && ton.effTyp != 0x3)
s3mLastGInstr[ii] = ton.instr;
- // EDx with no note does nothing in ST3 but retrigs in FT2, remove effect
- if (ton.effTyp == 0xE && (ton.eff & 0xF0) == 0xD0)
- {
- if (ton.ton == 0 || ton.ton == 97)
- {
- ton.effTyp = 0;
- ton.eff = 0;
- }
- }
-
- // EDx with a zero will prevent note/instr/vol from updating in ST3, remove everything
- if (ton.effTyp == 0xE && ton.eff == 0xD0)
- {
- ton.ton = 0;
- ton.instr = 0;
- ton.vol = 0;
- ton.effTyp = 0;
- ton.eff = 0;
- }
-
- // ECx with a zero does nothing in ST3 but cuts voice in FT2, remove effect
- if (ton.effTyp == 0xE && ton.eff == 0xC0)
- {
- ton.effTyp = 0;
- ton.eff = 0;
- }
-
- // Vxx with a value higher than 64 (0x40) does nothing in ST3, remove effect
- if (ton.effTyp == 0x10 && ton.eff > 0x40)
- {
- ton.effTyp = 0;
- ton.eff = 0;
- }
-
if (ton.effTyp > 35)
{
ton.effTyp = 0;
@@ -1610,10 +1535,10 @@
bool is16Bit = (h_S3MInstr.flags >> 2) & 1;
if (is16Bit) // 16-bit
- len *= 2;
+ len <<= 1;
if (stereoSample) // stereo
- len *= 2;
+ len <<= 1;
tmpSmp = (int8_t *)malloc(len + LOOP_FIX_LEN);
if (tmpSmp == NULL)
@@ -1683,9 +1608,9 @@
s->origPek = tmpSmp;
s->pek = s->origPek + SMP_DAT_OFFSET;
- s->len *= 2;
- s->repS *= 2;
- s->repL *= 2;
+ s->len <<= 1;
+ s->repS <<= 1;
+ s->repL <<= 1;
}
else
{
@@ -1712,74 +1637,6 @@
}
}
- // non-FT2: fix overflown 9xx and illegal 3xx slides
-
- for (i = 0; i < ap; i++)
- {
- if (pattTmp[i] == NULL)
- continue;
-
- for (k = 0; k < songTmp.antChn; k++)
- {
- check3xx = false;
- for (j = 0; j < 64; j++)
- {
- pattTon = &pattTmp[i][(j * MAX_VOICES) + k];
-
- // fix illegal 3xx slides
-
- if (pattTon->ton > 0 && pattTon->ton < 97)
- check3xx = pattTon->effTyp != 0x3;
-
- if (check3xx && pattTon->effTyp == 0x3)
- {
- if (pattTon->ton == 0 || pattTon->ton == 97)
- {
- pattTon->effTyp = 0;
- pattTon->eff = 0;
- }
- }
-
- /* In ST3 in GUS mode, an overflowed sample offset behaves like this:
- ** - Non-looped sample: Cut voice
- ** - Looped sample: Wrap around loop point
- **
- ** What we do here is to change the sample offset value to point to
- ** the wrapped sample loop position. This may be off by up to 256 bytes
- ** though...
- */
-
- if (pattTon->effTyp == 0x9 && pattTon->eff > 0 && pattTon->instr > 0 && pattTon->instr <= ai && ai <= 128)
- {
- instrTyp *ins = instrTmp[pattTon->instr];
- if (ins == NULL)
- continue; // empty instrument (sample)
-
- s = &ins->samp[0];
- if (s->len > 0 && (s->typ & 1)) // only handle non-empty looping samples
- {
- uint32_t loopEnd = s->repS + s->repL;
- uint32_t offset = pattTon->eff * 256;
-
- if (offset >= loopEnd)
- {
- if (s->repL >= 2)
- offset = s->repS + ((offset - loopEnd) % s->repL);
- else
- offset = s->repS;
-
- offset = (offset + (1 << 7)) >> 8; // convert to rounded sample offset value
- if (offset > 255)
- offset = 255;
-
- pattTon->eff = (uint8_t)offset;
- }
- }
- }
- }
- }
- }
-
fclose(f);
songTmp.antChn = countS3MChannels(ap);
@@ -2566,30 +2423,37 @@
// support non-even channel numbers
if (song.antChn & 1)
{
- if (++song.antChn > MAX_VOICES)
+ song.antChn++;
+ if (song.antChn > MAX_VOICES)
song.antChn = MAX_VOICES;
}
- if (song.repS > song.len)
+ if (song.len == 0)
+ song.len = 1;
+
+ if (song.repS >= song.len)
song.repS = 0;
song.globVol = 64;
- song.timer = 1;
setScrollBarEnd(SB_POS_ED, (song.len - 1) + 5);
setScrollBarPos(SB_POS_ED, 0, false);
resetChannels();
- setPos(0, 0, false);
+ setPos(0, 0, true);
setSpeed(song.speed);
editor.tmpPattern = editor.editPattern; // set kludge variable
editor.speed = song.speed;
editor.tempo = song.tempo;
- editor.timer = 1;
+ editor.timer = song.timer;
editor.globalVol = song.globVol;
- setFrqTab((loadedFormat == FORMAT_XM) ? linearFreqTable : false);
+ if (loadedFormat == FORMAT_XM)
+ setFrqTab(linearFreqTable);
+ else
+ setFrqTab(false);
+
unlockMixerCallback();
editor.currVolEnvPoint = 0;
@@ -2602,8 +2466,9 @@
updateChanNums();
resetWavRenderer();
clearPattMark();
- song.musicTime = 0;
resetTrimSizes();
+
+ song.musicTime = 0;
diskOpSetFilename(DISKOP_ITEM_MODULE, editor.tmpFilenameU);
--- a/src/ft2_nibbles.c
+++ b/src/ft2_nibbles.c
@@ -265,7 +265,7 @@
{
if (editor.NI_Play)
{
- okBox(0, "System message", "The highscore table is not available during play.");
+ okBox(0, "Nibbles message", "The highscore table is not available during play.");
return;
}
@@ -781,7 +781,7 @@
{
if (editor.NI_Play)
{
- if (okBox(2, "Nibbles request", "Restart the current game of Nibbles?") != 1)
+ if (okBox(2, "Nibbles request", "Restart current game of Nibbles?") != 1)
return;
}
--- a/src/ft2_pattern_draw.c
+++ b/src/ft2_pattern_draw.c
@@ -307,7 +307,7 @@
static void drawChannelNumbering(uint16_t yPos)
{
-#define CH_NUM_XPOS 29
+#define CH_NUM_XPOS 30
uint16_t xPos = CH_NUM_XPOS;
int32_t ch = editor.ui.channelOffset + 1;
--- a/src/ft2_pattern_ed.c
+++ b/src/ft2_pattern_ed.c
@@ -183,10 +183,10 @@
textOutShadow( 4, 126, PAL_FORGRND, PAL_DSKTOP2, "New number");
textOutShadow(129, 96, PAL_FORGRND, PAL_DSKTOP2, "Masking enable");
textOutShadow(114, 109, PAL_FORGRND, PAL_DSKTOP2, "Note");
- textOutShadow(114, 121, PAL_FORGRND, PAL_DSKTOP2, "Instrument number");
- textOutShadow(114, 134, PAL_FORGRND, PAL_DSKTOP2, "Volume column");
- textOutShadow(114, 147, PAL_FORGRND, PAL_DSKTOP2, "Effect digit 1");
- textOutShadow(114, 160, PAL_FORGRND, PAL_DSKTOP2, "Effect digit 2,3");
+ textOutShadow(114, 122, PAL_FORGRND, PAL_DSKTOP2, "Instrument number");
+ textOutShadow(114, 135, PAL_FORGRND, PAL_DSKTOP2, "Volume column");
+ textOutShadow(114, 148, PAL_FORGRND, PAL_DSKTOP2, "Effect digit 1");
+ textOutShadow(114, 161, PAL_FORGRND, PAL_DSKTOP2, "Effect digit 2,3");
charOutShadow(239, 95, PAL_FORGRND, PAL_DSKTOP2, 'C');
charOutShadow(258, 95, PAL_FORGRND, PAL_DSKTOP2, 'P');
@@ -680,8 +680,8 @@
textOutShadow(116, 5, PAL_FORGRND, PAL_DSKTOP2, "Sng.len.");
textOutShadow(116, 19, PAL_FORGRND, PAL_DSKTOP2, "Repst.");
- textOutShadow(222, 40, PAL_FORGRND, PAL_DSKTOP2, "Ptn.");
- textOutShadow(305, 40, PAL_FORGRND, PAL_DSKTOP2, "Ln.");
+ textOutShadow(222, 39, PAL_FORGRND, PAL_DSKTOP2, "Ptn.");
+ textOutShadow(305, 39, PAL_FORGRND, PAL_DSKTOP2, "Ln.");
editor.ui.instrSwitcherShown = true;
showInstrumentSwitcher();
@@ -2150,12 +2150,12 @@
if (editor.ui.extended)
{
x = 165;
- y = 6;
+ y = 5;
}
else
{
x = 59;
- y = 53;
+ y = 52;
}
hexOutBg(x, y, PAL_FORGRND, PAL_DESKTOP, (uint8_t)song.len, 2);
@@ -2168,12 +2168,12 @@
if (editor.ui.extended)
{
x = 165;
- y = 20;
+ y = 19;
}
else
{
x = 59;
- y = 65;
+ y = 64;
}
hexOutBg(x, y, PAL_FORGRND, PAL_DESKTOP, (uint8_t)song.repS, 2);
@@ -2207,8 +2207,8 @@
if (editor.ui.extended)
{
- x = 251;
- y = 40;
+ x = 252;
+ y = 39;
}
else
{
@@ -2226,7 +2226,7 @@
if (editor.ui.extended)
{
x = 326;
- y = 40;
+ y = 39;
}
else
{
--- a/src/ft2_pushbuttons.c
+++ b/src/ft2_pushbuttons.c
@@ -146,13 +146,13 @@
// ------ ABOUT SCREEN PUSHBUTTONS ------
//x, y, w, h, p, d, text #1, text #2, funcOnDown, funcOnUp
- { 5, 153, 59, 16, 0, 0, "Exit", NULL, NULL, exitAboutScreen },
+ { 4, 153, 59, 16, 0, 0, "Exit", NULL, NULL, exitAboutScreen },
// ------ HELP SCREEN PUSHBUTTONS ------
//x, y, w, h, p, d, text #1, text #2, funcOnDown, funcOnUp
{ 3, 155, 59, 16, 0, 0, "Exit", NULL, NULL, exitHelpScreen },
- { 611, 2, 18, 13, 1, 2, ARROW_UP_STRING, NULL, helpScrollUp, NULL },
- { 611, 158, 18, 13, 1, 2, ARROW_DOWN_STRING, NULL, helpScrollDown, NULL },
+ { 611, 2, 18, 13, 1, 3, ARROW_UP_STRING, NULL, helpScrollUp, NULL },
+ { 611, 158, 18, 13, 1, 3, ARROW_DOWN_STRING, NULL, helpScrollDown, NULL },
// ------ PATTERN EDITOR PUSHBUTTONS ------
//x, y, w, h, p, d, text #1, text #2, funcOnDown, funcOnUp
@@ -196,8 +196,8 @@
// ------ SAMPLE EDITOR PUSHBUTTONS ------
//x, y, w, h, p, d, text #1, text #2, funcOnDown, funcOnUp
- { 3, 331, 23, 13, 0, 0, ARROW_LEFT_STRING, NULL, scrollSampleDataLeft, NULL },
- { 606, 331, 23, 13, 0, 0, ARROW_RIGHT_STRING, NULL, scrollSampleDataRight, NULL },
+ { 3, 331, 23, 13, 1, 3, ARROW_LEFT_STRING, NULL, scrollSampleDataLeft, NULL },
+ { 606, 331, 23, 13, 1, 3, ARROW_RIGHT_STRING, NULL, scrollSampleDataRight, NULL },
{ 38, 356, 18, 13, 1, 4, ARROW_UP_STRING, NULL, sampPlayNoteUp, NULL },
{ 38, 368, 18, 13, 1, 4, ARROW_DOWN_STRING, NULL, sampPlayNoteDown, NULL },
{ 3, 382, 53, 16, 0, 0, "Stop", NULL, NULL, smpEdStop},
@@ -338,10 +338,10 @@
{ 113, 155, 93, 16, 0, 0, editor.ui.fullscreenButtonText, NULL, NULL, toggleFullScreen },
{ 370, 121, 18, 13, 1, 4, ARROW_UP_STRING, NULL, configQuantizeUp, NULL },
{ 387, 121, 18, 13, 1, 4, ARROW_DOWN_STRING, NULL, configQuantizeDown, NULL },
- { 594, 107, 18, 13, 1, 4, ARROW_UP_STRING, NULL, configMIDIChnUp, NULL },
- { 611, 107, 18, 13, 1, 4, ARROW_DOWN_STRING, NULL, configMIDIChnDown, NULL },
- { 594, 121, 18, 13, 1, 4, ARROW_UP_STRING, NULL, configMIDITransUp, NULL },
- { 611, 121, 18, 13, 1, 4, ARROW_DOWN_STRING, NULL, configMIDITransDown, NULL },
+ { 594, 106, 18, 13, 1, 4, ARROW_UP_STRING, NULL, configMIDIChnUp, NULL },
+ { 611, 106, 18, 13, 1, 4, ARROW_DOWN_STRING, NULL, configMIDIChnDown, NULL },
+ { 594, 120, 18, 13, 1, 4, ARROW_UP_STRING, NULL, configMIDITransUp, NULL },
+ { 611, 120, 18, 13, 1, 4, ARROW_DOWN_STRING, NULL, configMIDITransDown, NULL },
{ 556, 158, 22, 13, 1, 4, ARROW_LEFT_STRING, NULL, configMIDISensDown, NULL },
{ 607, 158, 22, 13, 1, 4, ARROW_RIGHT_STRING, NULL, configMIDISensUp, NULL },
@@ -377,8 +377,8 @@
{ 134, 2, 31, 13, 0, 0, "../", NULL, NULL, pbDiskOpParent },
{ 134, 16, 31, 12, 0, 0, "/", NULL, NULL, pbDiskOpRoot },
#endif
- { 335, 2, 18, 13, 0, 0, ARROW_UP_STRING, NULL, pbDiskOpListUp, NULL },
- { 335, 158, 18, 13, 0, 0, ARROW_DOWN_STRING, NULL, pbDiskOpListDown, NULL },
+ { 335, 2, 18, 13, 1, 3, ARROW_UP_STRING, NULL, pbDiskOpListUp, NULL },
+ { 335, 158, 18, 13, 1, 3, ARROW_DOWN_STRING, NULL, pbDiskOpListDown, NULL },
// ------ WAV RENDERER PUSHBUTTONS ------
//x, y, w, h, p, d, text #1, text #2, funcOnDown, funcOnUp
@@ -539,10 +539,10 @@
{
// button delay stuff
if (mouse.rightButtonPressed)
- buttonDelay = pushButton->delayFrames / 2;
- else if (pushButton->preDelay == 2 && (!mouse.firstTimePressingButton && ++tmpCounter >= 20)) // special mode
+ buttonDelay = pushButton->delayFrames >> 1;
+ else if (pushButton->preDelay == 2 && (!mouse.firstTimePressingButton && ++tmpCounter >= 50)) // special mode
buttonDelay = 0;
- else
+ else
buttonDelay = pushButton->delayFrames;
// main repeat delay
--- a/src/ft2_pushbuttons.h
+++ b/src/ft2_pushbuttons.h
@@ -342,7 +342,7 @@
};
// amount of frames to wait
-#define BUTTON_DOWN_DELAY 16
+#define BUTTON_DOWN_DELAY 25
// font #1/#2 special characters (used for buttons)
#define ARROW_UP_STRING "\x05"
--- a/src/ft2_radiobuttons.c
+++ b/src/ft2_radiobuttons.c
@@ -30,12 +30,12 @@
// ------ HELP SCREEN RADIOBUTTONS ------
//x, y, w, group, funcOnUp
- { 5, 16, 68, RB_GROUP_HELP, rbHelpFeatures },
- { 5, 31, 59, RB_GROUP_HELP, rbHelpEffects },
- { 5, 46, 70, RB_GROUP_HELP, rbHelpKeyboard },
- { 5, 61, 108, RB_GROUP_HELP, rbHelpHowToUseFT2 },
- { 5, 76, 100, RB_GROUP_HELP, rbHelpFAQ },
- { 5, 91, 85, RB_GROUP_HELP, rbHelpKnownBugs },
+ { 5, 18, 69, RB_GROUP_HELP, rbHelpFeatures },
+ { 5, 34, 60, RB_GROUP_HELP, rbHelpEffects },
+ { 5, 50, 71, RB_GROUP_HELP, rbHelpKeyboard },
+ { 5, 66, 109, RB_GROUP_HELP, rbHelpHowToUseFT2 },
+ { 5, 82, 101, RB_GROUP_HELP, rbHelpFAQ },
+ { 5, 98, 86, RB_GROUP_HELP, rbHelpKnownBugs },
// ------ NIBBLES SCREEN RADIOBUTTONS ------
//x, y, w, group, funcOnUp
@@ -63,12 +63,11 @@
// ------ CONFIG SCREEN LEFT RADIOBUTTONS ------
//x, y, w, group, funcOnUp
- { 4, 19, 87, RB_GROUP_CONFIG_SELECT, rbConfigIODevices },
- { 4, 35, 59, RB_GROUP_CONFIG_SELECT, rbConfigLayout },
- { 4, 51, 99, RB_GROUP_CONFIG_SELECT, rbConfigMiscellaneous },
-
+ { 5, 18, 85, RB_GROUP_CONFIG_SELECT, rbConfigIODevices },
+ { 5, 34, 57, RB_GROUP_CONFIG_SELECT, rbConfigLayout },
+ { 5, 50, 97, RB_GROUP_CONFIG_SELECT, rbConfigMiscellaneous },
#ifdef HAS_MIDI
- { 4, 67, 74, RB_GROUP_CONFIG_SELECT, rbConfigMidiInput },
+ { 5, 66, 72, RB_GROUP_CONFIG_SELECT, rbConfigMidiInput },
#endif
// ------ CONFIG AUDIO ------
--- a/src/ft2_replayer.c
+++ b/src/ft2_replayer.c
@@ -26,8 +26,7 @@
*/
static bool bxxOverflow;
-static uint16_t oldPeriod;
-static uint32_t oldRate, frequenceDivFactor, frequenceMulFactor;
+static int32_t oldPeriod, oldRate, frequenceDivFactor, frequenceMulFactor;
static tonTyp nilPatternLine;
// globally accessed
@@ -230,6 +229,8 @@
note2Period = amigaPeriods;
}
+ resetCachedFrequencyVars();
+
// update "frequency table" radiobutton, if it's shown
if (editor.ui.configScreenShown && editor.currConfigScreen == CONFIG_SCREEN_IO_DEVICES)
setConfigIORadioButtonStates();
@@ -367,7 +368,7 @@
indexQuotient = index / 768;
indexRemainder = index % 768;
- rate = ((uint64_t)logTab[indexRemainder] * frequenceMulFactor) >> LOG_TABLE_BITS;
+ rate = ((int64_t)logTab[indexRemainder] * frequenceMulFactor) >> LOG_TABLE_BITS;
shift = (14 - indexQuotient) & 0x1F;
if (shift != 0)
@@ -384,13 +385,13 @@
return rate;
}
-void resetOldRates(void)
+void resetCachedFrequencyVars(void)
{
- oldPeriod = 0;
+ oldPeriod = -1;
oldRate = 0;
- resetOldScopeRates();
- resetOldRevFreqs();
+ resetCachedScopeVars();
+ resetCachedMixerVars();
}
static void startTone(uint8_t ton, uint8_t effTyp, uint8_t eff, stmTyp *ch)
@@ -1320,10 +1321,10 @@
** Also, vol envelope range is now 0..16384 instead of being shifted to 0..64
*/
- uint32_t vol1 = song.globVol * ch->outVol * ch->fadeOutAmp; // 0..64 * 0..64 * 0..32768 = 0..134217728
- uint32_t vol2 = envVal << 7; // 0..16384 * 2^7 = 0..2097152
+ int32_t vol1 = song.globVol * ch->outVol * ch->fadeOutAmp; // 0..64 * 0..64 * 0..32768 = 0..134217728
+ int32_t vol2 = envVal << 7; // 0..16384 * 2^7 = 0..2097152
- vol = ((uint64_t)vol1 * vol2) >> 32; // 0..65536
+ vol = ((int64_t)vol1 * vol2) >> 32; // 0..65536
ch->status |= IS_Vol;
}
@@ -1330,7 +1331,7 @@
else
{
// calculate with four times more precision (finalVol = 0..65535)
- vol = (song.globVol * ch->outVol * ch->fadeOutAmp) >> 11; // 0..64 * 0..64 * 0..32768 = 0..65536
+ vol = ((song.globVol * ch->outVol * ch->fadeOutAmp) + (1 << 10)) >> 11; // 0..64 * 0..64 * 0..32768 -> 0..65536 (rounded)
}
if (vol > 65535)
@@ -3058,7 +3059,7 @@
stopAllScopes();
resetAudioDither();
- resetOldRates();
+ resetCachedFrequencyVars();
// wait for scope thread to finish, so that we know pointers aren't deprecated
while (editor.scopeThreadMutex);
--- a/src/ft2_replayer.h
+++ b/src/ft2_replayer.h
@@ -241,7 +241,7 @@
void fixSampleName(int16_t nr); // removes spaces from right side of ins/smp names
void calcReplayRate(int32_t rate);
-void resetOldRates(void);
+void resetCachedFrequencyVars(void);
void tuneSample(sampleTyp *s, int32_t midCFreq);
uint32_t getFrequenceValue(uint16_t period);
--- a/src/ft2_sample_ed.c
+++ b/src/ft2_sample_ed.c
@@ -1013,7 +1013,7 @@
viewSizeSamples = smpEd_ViewSize;
if (s->typ & 16)
- viewSizeSamples /= 2;
+ viewSizeSamples >>= 1;
if (viewSizeSamples <= SAMPLE_AREA_WIDTH)
{
@@ -1319,18 +1319,13 @@
return;
if (mouse.rightButtonPressed)
- {
scrollAmount = smpEd_ViewSize / 14; // rounded from 16 (70Hz)
- if (scrollAmount < 1)
- scrollAmount = 1;
- }
else
- {
scrollAmount = smpEd_ViewSize / 27; // rounded from 32 (70Hz)
- if (scrollAmount < 1)
- scrollAmount = 1;
- }
+ if (scrollAmount < 1)
+ scrollAmount = 1;
+
smpEd_ScrPos -= scrollAmount;
if (smpEd_ScrPos < 0)
smpEd_ScrPos = 0;
@@ -1351,18 +1346,13 @@
return;
if (mouse.rightButtonPressed)
- {
scrollAmount = smpEd_ViewSize / 14; // was 16 (70Hz->60Hz)
- if (scrollAmount < 1)
- scrollAmount = 1;
- }
else
- {
scrollAmount = smpEd_ViewSize / 27; // was 32 (70Hz->60Hz)
- if (scrollAmount < 1)
- scrollAmount = 1;
- }
+ if (scrollAmount < 1)
+ scrollAmount = 1;
+
smpEd_ScrPos += scrollAmount;
if (smpEd_ScrPos+smpEd_ViewSize > sampleLen)
smpEd_ScrPos = sampleLen - smpEd_ViewSize;
@@ -2694,18 +2684,15 @@
if (s == NULL || s->pek == NULL || s->len <= 0)
return;
- bool hasLoop = s->typ & 3;
- int32_t loopEnd = s->repS + s->repL;
+ if (okBox(1, "System request", "Minimize sample?") != 1)
+ return;
- if (!hasLoop || (loopEnd >= s->len || loopEnd == 0))
+ bool hasLoop = s->typ & 3;
+ if (hasLoop && s->len > s->repS+s->repL && s->repL < s->len)
{
- okBox(0, "System message", "Sample is already minimized.");
- }
- else
- {
lockMixerCallback();
- s->len = loopEnd;
+ s->len = s->repS + s->repL;
newPtr = (int8_t *)realloc(s->origPek, s->len + LOOP_FIX_LEN);
if (newPtr != NULL)
@@ -2714,6 +2701,8 @@
s->pek = s->origPek + SMP_DAT_OFFSET;
}
+ // Note: we don't need to make a call to fixSample()
+
unlockMixerCallback();
updateSampleEditorSample();
@@ -2897,9 +2886,9 @@
textOutShadow(371, 369, PAL_FORGRND, PAL_DSKTOP2, "Forward");
textOutShadow(371, 386, PAL_FORGRND, PAL_DSKTOP2, "Pingpong");
textOutShadow(446, 369, PAL_FORGRND, PAL_DSKTOP2, "8-bit");
- textOutShadow(445, 385, PAL_FORGRND, PAL_DSKTOP2, "16-bit");
- textOutShadow(488, 349, PAL_FORGRND, PAL_DSKTOP2, "Display");
- textOutShadow(488, 361, PAL_FORGRND, PAL_DSKTOP2, "Length");
+ textOutShadow(445, 384, PAL_FORGRND, PAL_DSKTOP2, "16-bit");
+ textOutShadow(488, 350, PAL_FORGRND, PAL_DSKTOP2, "Display");
+ textOutShadow(488, 362, PAL_FORGRND, PAL_DSKTOP2, "Length");
textOutShadow(488, 375, PAL_FORGRND, PAL_DSKTOP2, "Repeat");
textOutShadow(488, 387, PAL_FORGRND, PAL_DSKTOP2, "Replen.");
@@ -3233,7 +3222,7 @@
int32_t y = lastDrawY - vl;
uint32_t x = lastDrawX - p;
- uint32_t xMul = 0xFFFFFFFF;
+ int32_t xMul = 0xFFFFFFFF;
if (x != 0)
xMul /= x;
@@ -3276,7 +3265,7 @@
int32_t y = lastDrawY - vl;
uint32_t x = lastDrawX - p;
- uint32_t xMul = 0xFFFFFFFF;
+ int32_t xMul = 0xFFFFFFFF;
if (x != 0)
xMul /= x;
@@ -3430,10 +3419,10 @@
textOutShadow( 4, 96, PAL_FORGRND, PAL_DSKTOP2, "Rng.:");
charOutShadow(91, 95, PAL_FORGRND, PAL_DSKTOP2, '-');
- textOutShadow( 4, 109, PAL_FORGRND, PAL_DSKTOP2, "Range size");
- textOutShadow( 4, 123, PAL_FORGRND, PAL_DSKTOP2, "Copy buf. size");
+ textOutShadow( 4, 110, PAL_FORGRND, PAL_DSKTOP2, "Range size");
+ textOutShadow( 4, 124, PAL_FORGRND, PAL_DSKTOP2, "Copy buf. size");
- textOutShadow(162, 95, PAL_FORGRND, PAL_DSKTOP2, "Src.instr.");
+ textOutShadow(162, 96, PAL_FORGRND, PAL_DSKTOP2, "Src.instr.");
textOutShadow(245, 96, PAL_FORGRND, PAL_DSKTOP2, "smp.");
textOutShadow(162, 109, PAL_FORGRND, PAL_DSKTOP2, "Dest.instr.");
textOutShadow(245, 109, PAL_FORGRND, PAL_DSKTOP2, "smp.");
--- a/src/ft2_sample_ed_features.c
+++ b/src/ft2_sample_ed_features.c
@@ -121,7 +121,7 @@
p1 = s->pek;
// don't use the potentially clamped newLen value here
- delta64 = ((uint64_t)s->len << 32) / (uint64_t)(s->len * dLenMul); // 32.32 fixed point delta
+ delta64 = ((int64_t)s->len << 32) / (int64_t)(s->len * dLenMul); // 32.32 fixed point delta
posFrac64 = 0; // 32.32 fixed point position.fraction
@@ -660,8 +660,8 @@
hLine(x + 2, y + h - 3, w - 4, PAL_BUTTON1);
textOutShadow(177, 226, PAL_FORGRND, PAL_BUTTON2, "Number of echoes");
- textOutShadow(177, 239, PAL_FORGRND, PAL_BUTTON2, "Echo distance");
- textOutShadow(177, 253, PAL_FORGRND, PAL_BUTTON2, "Fade out");
+ textOutShadow(177, 240, PAL_FORGRND, PAL_BUTTON2, "Echo distance");
+ textOutShadow(177, 254, PAL_FORGRND, PAL_BUTTON2, "Fade out");
textOutShadow(192, 270, PAL_FORGRND, PAL_BUTTON2, "Add memory to sample");
assert(echo_nEcho <= 1024);
@@ -1510,7 +1510,7 @@
hLine(x + 2, y + h - 3, w - 4, PAL_BUTTON1);
textOutShadow(172, 236, PAL_FORGRND, PAL_BUTTON2, "Start volume");
- textOutShadow(172, 249, PAL_FORGRND, PAL_BUTTON2, "End volume");
+ textOutShadow(172, 250, PAL_FORGRND, PAL_BUTTON2, "End volume");
charOutShadow(282, 236, PAL_FORGRND, PAL_BUTTON2, '%');
charOutShadow(282, 250, PAL_FORGRND, PAL_BUTTON2, '%');
--- a/src/ft2_scopes.c
+++ b/src/ft2_scopes.c
@@ -48,9 +48,9 @@
lastChInstr_t lastChInstr[MAX_VOICES]; // global
-void resetOldScopeRates(void)
+void resetCachedScopeVars(void)
{
- oldVoiceDelta = 0;
+ oldVoiceDelta = 0xFFFFFFFF;
oldSFrq = 0;
}
@@ -126,6 +126,7 @@
static void drawScopeNumber(uint16_t scopeXOffs, uint16_t scopeYOffs, uint8_t channel, bool outline)
{
+ scopeXOffs++;
scopeYOffs++;
channel++;
@@ -313,7 +314,7 @@
return false;
}
-static void scopeTrigger(uint8_t ch, sampleTyp *s, int32_t playOffset)
+static void scopeTrigger(int32_t ch, sampleTyp *s, int32_t playOffset)
{
bool sampleIs16Bit;
uint8_t loopType;
@@ -522,7 +523,7 @@
// draw rec. symbol (if enabled)
if (config.multiRecChn[i])
- blit(scopeXOffs, scopeYOffs + 31, bmp.scopeRec, 13, 4);
+ blit(scopeXOffs + 1, scopeYOffs + 31, bmp.scopeRec, 13, 4);
scopeXOffs += scopeDrawLen + 3; // align x to next scope
}
@@ -572,7 +573,7 @@
if (instr[ch->instrNr] != NULL)
{
smpPtr = &instr[ch->instrNr]->samp[ch->sampleNr];
- scopeTrigger((uint8_t)i, smpPtr, ch->smpStartPos);
+ scopeTrigger(i, smpPtr, ch->smpStartPos);
// set stuff used by Smp. Ed. for sampling position line
--- a/src/ft2_scopes.h
+++ b/src/ft2_scopes.h
@@ -4,7 +4,7 @@
#include <stdbool.h>
#include "ft2_header.h"
-void resetOldScopeRates(void);
+void resetCachedScopeVars(void);
int32_t getSamplePosition(uint8_t ch);
void stopAllScopes(void);
void refreshScopes(void);
--- a/vs2019_project/ft2-clone/ft2-clone.vcxproj
+++ b/vs2019_project/ft2-clone/ft2-clone.vcxproj
@@ -278,6 +278,7 @@
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<OpenMPSupport>false</OpenMPSupport>
<LanguageStandard>stdcpplatest</LanguageStandard>
+ <OmitFramePointers>false</OmitFramePointers>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>