Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package ft2-clone for openSUSE:Factory checked in at 2026-03-05 17:30:33 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/ft2-clone (Old) and /work/SRC/openSUSE:Factory/.ft2-clone.new.561 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "ft2-clone" Thu Mar 5 17:30:33 2026 rev:34 rq:1336694 version:2.08 Changes: -------- --- /work/SRC/openSUSE:Factory/ft2-clone/ft2-clone.changes 2026-03-03 15:33:14.746782719 +0100 +++ /work/SRC/openSUSE:Factory/.ft2-clone.new.561/ft2-clone.changes 2026-03-05 17:33:12.359572926 +0100 @@ -1,0 +2,19 @@ +Wed Mar 4 19:58:06 UTC 2026 - Martin Hauke <[email protected]> + +- Update to version 2.08 + * Visuals->audio sync was partially broken since v1.52 + (27.02.2022)! This was a minor issue anyway, as it wasn't that + easy to notice it. +- Update to version 2.07 + * When loading stereo MP3 samples, immediately ask which channel + to read instead of loading it first, then ask. + * Bug fix: Mouse cursor would accidentally be set from busy to + normal after deciding what to do when loading a stereo sample + (system request). This was wrong, it should be set to normal + after sample loading is done. + * When clicking on the program while it was not in focus, let + the mouse click be handled. Fixes having to click twice on a + system request dialog button when dropping a file onto the + program. + +------------------------------------------------------------------- Old: ---- ft2-clone-2.06.tar.gz New: ---- ft2-clone-2.08.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ ft2-clone.spec ++++++ --- /var/tmp/diff_new_pack.4OjKCD/_old 2026-03-05 17:33:12.971598340 +0100 +++ /var/tmp/diff_new_pack.4OjKCD/_new 2026-03-05 17:33:12.971598340 +0100 @@ -17,7 +17,7 @@ Name: ft2-clone -Version: 2.06 +Version: 2.08 Release: 0 Summary: Fasttracker II clone License: BSD-3-Clause AND CC-BY-NC-SA-4.0 ++++++ ft2-clone-2.06.tar.gz -> ft2-clone-2.08.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ft2-clone-2.06/src/ft2_audio.c new/ft2-clone-2.08/src/ft2_audio.c --- old/ft2-clone-2.06/src/ft2_audio.c 2026-03-02 16:05:58.000000000 +0100 +++ new/ft2-clone-2.08/src/ft2_audio.c 2026-03-04 12:22:13.000000000 +0100 @@ -917,17 +917,14 @@ static void calcAudioLatencyVars(int32_t audioBufferSize, int32_t audioFreq) { - double dInt; - if (audioFreq == 0) return; - const double dAudioLatencySecs = audioBufferSize / (double)audioFreq; - - double dFrac = modf(dAudioLatencySecs * editor.dPerfFreq, &dInt); + const double dAudioLatencyTime = (audioBufferSize / (double)audioFreq) * (double)hpcFreq.freq64; + double dAudioLatencyTimeInt, dAudioLatencyTimeFrac = modf(dAudioLatencyTime, &dAudioLatencyTimeInt); - audio.audLatencyPerfValInt = (uint32_t)dInt; - audio.audLatencyPerfValFrac = (uint64_t)((dFrac * TICK_TIME_FRAC_SCALE) + 0.5); // rounded + audio.audLatencyPerfValInt = (uint32_t)dAudioLatencyTimeInt; + audio.audLatencyPerfValFrac = (uint64_t)(dAudioLatencyTimeFrac * TICK_TIME_FRAC_SCALE); } static void setLastWorkingAudioDevName(void) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ft2-clone-2.06/src/ft2_header.h new/ft2-clone-2.08/src/ft2_header.h --- old/ft2-clone-2.06/src/ft2_header.h 2026-03-02 16:05:58.000000000 +0100 +++ new/ft2-clone-2.08/src/ft2_header.h 2026-03-04 12:22:13.000000000 +0100 @@ -14,7 +14,7 @@ #endif #include "ft2_replayer.h" -#define PROG_VER_STR "2.06" +#define PROG_VER_STR "2.08" // do NOT change these! It will only mess things up... diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ft2-clone-2.06/src/ft2_hpc.c new/ft2-clone-2.08/src/ft2_hpc.c --- old/ft2-clone-2.06/src/ft2_hpc.c 2026-03-02 16:05:58.000000000 +0100 +++ new/ft2-clone-2.08/src/ft2_hpc.c 2026-03-04 12:22:13.000000000 +0100 @@ -21,9 +21,9 @@ #include <stdbool.h> #include "ft2_hpc.h" -#define FRAC_BITS 63 /* leaves one bit for frac overflow test */ -#define FRAC_SCALE (1ULL << FRAC_BITS) -#define FRAC_MASK (FRAC_SCALE-1) +#define DURATION_FRAC_BITS 52 /* more makes little sense */ +#define DURATION_FRAC_SCALE (1ULL << DURATION_FRAC_BITS) +#define DURATION_FRAC_MASK (DURATION_FRAC_SCALE-1) hpcFreq_t hpcFreq; @@ -80,52 +80,17 @@ hpcFreq.dFreqMulMicro = (1000.0 * 1000.0) / dFreq; } -// returns 64-bit fractional part of u64 divided by u32 -static uint64_t getFrac64FromU64DivU32(uint64_t dividend, uint32_t divisor) +void hpc_SetDurationInHz(hpc_t *hpc, double dHz) { - if (dividend == 0 || divisor == 0 || divisor >= dividend) - return 0; + const double dTickTime = (double)hpcFreq.freq64 / dHz; + double dTimeInt, dTimeFrac = modf(dTickTime, &dTimeInt); - dividend %= divisor; - - if (dividend == 0) - return 0; - - const uint32_t quotient = (uint32_t)((dividend << 32) / divisor); - const uint32_t remainder = (uint32_t)((dividend << 32) % divisor); - - const uint32_t resultHi = quotient; - const uint32_t resultLo = (uint32_t)(((uint64_t)remainder << 32) / divisor); - - return ((uint64_t)resultHi << 32) | resultLo; -} - -void hpc_SetDurationInHz(hpc_t *hpc, double dHz) // dHz = max 4095.999inf Hz (0.24ms) -{ -#define BITS_IN_UINT32 32 - - /* 20 = Good compensation between fraction bits and max integer size. - ** Most non-realtime OSes probably can't do a thread delay with such a - ** high precision ( 0.24ms, 1000/(2^(32-20)-1) ) anyway. - */ -#define INPUT_FRAC_BITS 20 -#define INPUT_FRAC_SCALE (1UL << INPUT_FRAC_BITS) -#define INPUT_INT_MAX ((1UL << (BITS_IN_UINT32-INPUT_FRAC_BITS))-1) - - if (dHz > INPUT_INT_MAX) - dHz = INPUT_INT_MAX; - - const uint32_t fpHz = (uint32_t)((dHz * INPUT_FRAC_SCALE) + 0.5); - - // set 64:63fp value - const uint64_t fpFreq64 = hpcFreq.freq64 << INPUT_FRAC_BITS; - hpc->durationInt = fpFreq64 / fpHz; - hpc->durationFrac = getFrac64FromU64DivU32(fpFreq64, fpHz) >> 1; // 64 -> 63 bits (1 bit for frac overflow test) - - hpc->resetFrame = ((uint64_t)fpHz * (60 * 30)) / INPUT_FRAC_SCALE; // reset counters every half an hour + hpc->durationInt = (uint32_t)dTimeInt; + hpc->durationFrac = (uint64_t)(dTimeFrac * DURATION_FRAC_SCALE); + hpc->resetFrame = (uint64_t)(dHz * (60*30)); // reset counters every half an hour } -void hpc_SetDurationInMs(hpc_t *hpc, double dMs) // dMs = minimum 0.2442002442 ms +void hpc_SetDurationInMs(hpc_t *hpc, double dMs) { hpc_SetDurationInHz(hpc, 1000.0 / dMs); } @@ -172,9 +137,9 @@ // handle fractional part hpc->endTimeFrac += hpc->durationFrac; - if (hpc->endTimeFrac >= FRAC_SCALE) + if (hpc->endTimeFrac >= DURATION_FRAC_SCALE) { - hpc->endTimeFrac &= FRAC_MASK; + hpc->endTimeFrac &= DURATION_FRAC_MASK; hpc->endTimeInt++; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ft2-clone-2.06/src/ft2_hpc.h new/ft2-clone-2.08/src/ft2_hpc.h --- old/ft2-clone-2.06/src/ft2_hpc.h 2026-03-02 16:05:58.000000000 +0100 +++ new/ft2-clone-2.08/src/ft2_hpc.h 2026-03-04 12:22:13.000000000 +0100 @@ -19,7 +19,7 @@ extern hpcFreq_t hpcFreq; void hpc_Init(void); -void hpc_SetDurationInHz(hpc_t *hpc, double dHz); // dHz = max 4095.999inf Hz (0.24ms) -void hpc_SetDurationInMs(hpc_t *hpc, double dMs); // dMs = minimum 0.2442002442 ms +void hpc_SetDurationInHz(hpc_t *hpc, double dHz); +void hpc_SetDurationInMs(hpc_t *hpc, double dMs); void hpc_ResetCounters(hpc_t *hpc); void hpc_Wait(hpc_t *hpc); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ft2-clone-2.06/src/ft2_main.c new/ft2-clone-2.08/src/ft2_main.c --- old/ft2-clone-2.06/src/ft2_main.c 2026-03-02 16:05:58.000000000 +0100 +++ new/ft2-clone-2.08/src/ft2_main.c 2026-03-04 12:22:13.000000000 +0100 @@ -51,6 +51,25 @@ int main(int argc, char *argv[]) { +#ifdef _WIN32 // test for SSE/SSE2 presence very first, to make sure no SSE/SSE2 code is attempted to be ran + cpu.hasSSE = SDL_HasSSE(); + cpu.hasSSE2 = SDL_HasSSE2(); + + if (!cpu.hasSSE) + { + MessageBoxA(NULL, "Your computer's processor doesn't have the SSE instruction set " \ + "which is needed for this program to run. Sorry!", "Error", MB_ICONEXCLAMATION); + return 0; + } + + if (!cpu.hasSSE2) + { + MessageBoxA(NULL, "Your computer's processor doesn't have the SSE2 instruction set " \ + "which is needed for this program to run. Sorry!", "Error", MB_ICONEXCLAMATION); + return 0; + } +#endif + #if defined _WIN32 || defined __APPLE__ SDL_version sdlVer; #endif @@ -93,6 +112,8 @@ } #endif + hpc_Init(); + // ALT+F4 is used in FT2, but is "close program" in some cases... #if SDL_MINOR_VERSION >= 24 || (SDL_MINOR_VERSION == 0 && SDL_PATCHLEVEL >= 4) SDL_SetHint("SDL_WINDOWS_NO_CLOSE_ON_ALT_F4", "1"); @@ -103,20 +124,6 @@ SetProcessDPIAware(); #endif - if (!cpu.hasSSE) - { - showErrorMsgBox("Your computer's processor doesn't have the SSE instruction set\n" \ - "which is needed for this program to run. Sorry!"); - return 0; - } - - if (!cpu.hasSSE2) - { - showErrorMsgBox("Your computer's processor doesn't have the SSE2 instruction set\n" \ - "which is needed for this program to run. Sorry!"); - return 0; - } - disableWasapi(); // disable problematic WASAPI SDL2 audio driver on Windows (causes clicks/pops sometimes...) // 13.03.2020: This is still needed with SDL 2.0.12... #endif @@ -136,6 +143,7 @@ return 1; } + SDL_SetHint("SDL_MOUSE_FOCUS_CLICKTHROUGH", "1"); SDL_EventState(SDL_DROPFILE, SDL_ENABLE); /* Text input is started by default in SDL2, turn it off to remove ~2ms spikes per key press. @@ -144,7 +152,6 @@ */ SDL_StopTextInput(); - hpc_Init(); hpc_SetDurationInHz(&video.vblankHpc, VBLANK_HZ); #ifdef __APPLE__ @@ -266,9 +273,6 @@ { srand((uint32_t)time(NULL)); - cpu.hasSSE = SDL_HasSSE(); - cpu.hasSSE2 = SDL_HasSSE2(); - // clear common structs #ifdef HAS_MIDI memset(&midi, 0, sizeof (midi)); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ft2-clone-2.06/src/ft2_replayer.c new/ft2-clone-2.08/src/ft2_replayer.c --- old/ft2-clone-2.06/src/ft2_replayer.c 2026-03-02 16:05:58.000000000 +0100 +++ new/ft2-clone-2.08/src/ft2_replayer.c 2026-03-04 12:22:13.000000000 +0100 @@ -463,22 +463,20 @@ for (int32_t bpm = MIN_BPM; bpm <= MAX_BPM; bpm++) { const int32_t i = bpm - MIN_BPM; // index for tables - const double dBpmHz = bpm / 2.5; - const double dSamplesPerTick = audioFreq / dBpmHz; - double dSamplesPerTickInt; - double dSamplesPerTickFrac = modf(dSamplesPerTick, &dSamplesPerTickInt); + const double dSamplesPerTick = audioFreq / dBpmHz; + double dSamplesPerTickInt, dSamplesPerTickFrac = modf(dSamplesPerTick, &dSamplesPerTickInt); audio.samplesPerTickIntTab[i] = (uint32_t)dSamplesPerTickInt; - audio.samplesPerTickFracTab[i] = (uint64_t)((dSamplesPerTickFrac * BPM_FRAC_SCALE) + 0.5); // rounded + audio.samplesPerTickFracTab[i] = (uint64_t)(dSamplesPerTickFrac * BPM_FRAC_SCALE); - // BPM Hz -> tick length for performance counter (syncing visuals to audio) - double dTimeInt; - double dTimeFrac = modf(editor.dPerfFreq / dBpmHz, &dTimeInt); + // for performance counter (syncing visuals to audio) + double dTickTime = (double)hpcFreq.freq64 / dBpmHz; + double dTickTimeInt, dTickTimeFrac = modf(dTickTime, &dTickTimeInt); - audio.tickTimeIntTab[i] = (uint32_t)dTimeInt; - audio.tickTimeFracTab[i] = (uint64_t)((dTimeFrac * TICK_TIME_FRAC_SCALE) + 0.5); // rounded + audio.tickTimeIntTab[i] = (uint32_t)dTickTimeInt; + audio.tickTimeFracTab[i] = (uint64_t)(dTickTimeFrac * TICK_TIME_FRAC_SCALE); } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ft2-clone-2.06/src/ft2_structs.h new/ft2-clone-2.08/src/ft2_structs.h --- old/ft2-clone-2.06/src/ft2_structs.h 2026-03-02 16:05:58.000000000 +0100 +++ new/ft2-clone-2.08/src/ft2_structs.h 2026-03-04 12:22:13.000000000 +0100 @@ -36,7 +36,6 @@ uint16_t tmpPattern, editPattern, BPM, speed, tick, ptnCursorY; int32_t keyOffNr, keyOffTime[MAX_CHANNELS]; uint32_t framesPassed, wavRendererTime; - double dPerfFreq, dPerfFreqMulMicro, dPerfFreqMulMs; } editor_t; typedef struct ui_t diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ft2-clone-2.06/src/smploaders/ft2_load_aiff.c new/ft2-clone-2.08/src/smploaders/ft2_load_aiff.c --- old/ft2-clone-2.06/src/smploaders/ft2_load_aiff.c 2026-03-02 16:05:58.000000000 +0100 +++ new/ft2-clone-2.08/src/smploaders/ft2_load_aiff.c 2026-03-04 12:22:13.000000000 +0100 @@ -10,6 +10,7 @@ #include <stdbool.h> #include <math.h> #include "../ft2_header.h" +#include "../ft2_mouse.h" #include "../ft2_audio.h" #include "../ft2_sample_ed.h" #include "../ft2_sysreqs.h" @@ -149,7 +150,10 @@ int16_t stereoSampleLoadMode = -1; if (aiffIsStereo(f)) + { stereoSampleLoadMode = loaderSysReq(4, "System request", "This is a stereo sample. Which channel do you want to read?", NULL); + setMouseBusy(true); + } // read sample data diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ft2-clone-2.06/src/smploaders/ft2_load_flac.c new/ft2-clone-2.08/src/smploaders/ft2_load_flac.c --- old/ft2-clone-2.06/src/smploaders/ft2_load_flac.c 2026-03-02 16:05:58.000000000 +0100 +++ new/ft2-clone-2.08/src/smploaders/ft2_load_flac.c 2026-03-04 12:22:13.000000000 +0100 @@ -21,6 +21,7 @@ #include <unistd.h> #endif #include "../ft2_header.h" +#include "../ft2_mouse.h" #include "../ft2_audio.h" #include "../ft2_sample_ed.h" #include "../ft2_sysreqs.h" @@ -208,7 +209,10 @@ stereoSampleLoadMode = -1; if (numChannels == 2) + { stereoSampleLoadMode = loaderSysReq(4, "System request", "This is a stereo sample. Which channel do you want to read?", NULL); + setMouseBusy(true); + } } // check for RIFF chunks (loop/vol/pan information) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ft2-clone-2.06/src/smploaders/ft2_load_mp3.c new/ft2-clone-2.08/src/smploaders/ft2_load_mp3.c --- old/ft2-clone-2.06/src/smploaders/ft2_load_mp3.c 2026-03-02 16:05:58.000000000 +0100 +++ new/ft2-clone-2.08/src/smploaders/ft2_load_mp3.c 2026-03-04 12:22:13.000000000 +0100 @@ -21,10 +21,13 @@ #define MINIMP3_IMPLEMENTATION #include "minimp3_ex.h" #include "../ft2_header.h" +#include "../ft2_mouse.h" #include "../ft2_sample_ed.h" #include "../ft2_sysreqs.h" #include "../ft2_sample_loader.h" +static bool mp3IsStereo = true; + bool detectMP3(FILE *f) { uint8_t h[10]; @@ -41,10 +44,12 @@ fseek(f, 10+bytesToSkip, SEEK_SET); - h[0] = h[1] = h[2] = 0; - fread(h, 1, 3, f); + h[0] = h[1] = h[2] = h[3] = 0; + fread(h, 1, 4, f); } + mp3IsStereo = (((h[3]) & 0xC0) != 0xC0); + // we can now test if this is an MP3 file return h[0] == 0xFF && @@ -67,6 +72,13 @@ return false; } + int16_t stereoAction = -1; + if (mp3IsStereo) + { + stereoAction = loaderSysReq(4, "System request", "This is a stereo sample. Which channel do you want to read?", NULL); + setMouseBusy(true); + } + if (fread(buf, 1, filesize, f) != filesize) { free(buf); @@ -100,9 +112,8 @@ int16_t *src16 = (int16_t *)info.buffer; uint32_t sampleLength = (uint32_t)info.samples; - bool stereo = (info.channels == 2); - if (stereo) + if (mp3IsStereo) sampleLength >>= 1; if (!allocateSmpData(s, sampleLength, true)) @@ -112,9 +123,8 @@ } int16_t *out16 = (int16_t *)s->dataPtr; - if (stereo) + if (mp3IsStereo) { - int16_t stereoAction = loaderSysReq(4, "System request", "This is a stereo sample. Which channel do you want to read?", NULL); switch (stereoAction) { case STEREO_SAMPLE_READ_LEFT_CHANNEL: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ft2-clone-2.06/src/smploaders/ft2_load_wav.c new/ft2-clone-2.08/src/smploaders/ft2_load_wav.c --- old/ft2-clone-2.06/src/smploaders/ft2_load_wav.c 2026-03-02 16:05:58.000000000 +0100 +++ new/ft2-clone-2.08/src/smploaders/ft2_load_wav.c 2026-03-04 12:22:13.000000000 +0100 @@ -9,6 +9,7 @@ #include <stdint.h> #include <stdbool.h> #include "../ft2_header.h" +#include "../ft2_mouse.h" #include "../ft2_audio.h" #include "../ft2_sample_ed.h" #include "../ft2_sysreqs.h" @@ -188,7 +189,10 @@ int16_t stereoSampleLoadMode = -1; if (wavIsStereo(f)) + { stereoSampleLoadMode = loaderSysReq(4, "System request", "This is a stereo sample. Which channel do you want to read?", NULL); + setMouseBusy(true); + } if (bitsPerSample == 8) // 8-BIT INTEGER SAMPLE {
