ref: 4beea686fd27e6c6ba19ec52ea8d80c2a7cc56eb
dir: /src/pt2_helpers.c/
// for finding memory leaks in debug mode with Visual Studio #if defined _DEBUG && defined _MSC_VER #include <crtdbg.h> #endif #include <SDL2/SDL.h> #include <stdarg.h> #include <stdio.h> #include <stdint.h> #include <stdbool.h> #include <ctype.h> // toupper() #ifndef _WIN32 #include <unistd.h> #else #define WIN32_MEAN_AND_LEAN #include <windows.h> #endif #include "pt2_helpers.h" #include "pt2_header.h" #include "pt2_tables.h" #include "pt2_palette.h" extern SDL_Window *window; // pt_main.c // used for Windows usleep() implementation #ifdef _WIN32 static NTSTATUS (__stdcall *NtDelayExecution)(BOOL Alertable, PLARGE_INTEGER DelayInterval); #endif // usleep() implementation for Windows #ifdef _WIN32 void usleep(uint32_t usec) { LARGE_INTEGER lpDueTime; if (NtDelayExecution == NULL) { // NtDelayExecution() is not available (shouldn't happen), use regular sleep() Sleep(usec / 1000); } else { // this prevents a 64-bit MUL (will not overflow with typical values anyway) lpDueTime.HighPart = 0xFFFFFFFF; lpDueTime.LowPart = (DWORD)(-10 * (int32_t)usec); NtDelayExecution(false, &lpDueTime); } } void setupWin32Usleep(void) { NtDelayExecution = (NTSTATUS (__stdcall *)(BOOL, PLARGE_INTEGER))GetProcAddress(GetModuleHandle("ntdll.dll"), "NtDelayExecution"); timeBeginPeriod(0); // enter highest timer resolution } void freeWin32Usleep(void) { timeEndPeriod(0); // exit highest timer resolution } #endif void showErrorMsgBox(const char *fmt, ...) { char strBuf[1024]; va_list args; // format the text string va_start(args, fmt); vsnprintf(strBuf, sizeof (strBuf), fmt, args); va_end(args); // window can be NULL here, no problem... SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Critical Error", strBuf, window); } void sanitizeFilenameChar(char *chr) { // some of these are legal on GNU/Linux and macOS, but whatever... if (*chr == '\\') *chr = ' '; else if (*chr == '/') *chr = ' '; else if (*chr == ':') *chr = ' '; else if (*chr == '*') *chr = ' '; else if (*chr == '?') *chr = ' '; else if (*chr == '\"') *chr = ' '; else if (*chr == '<') *chr = ' '; else if (*chr == '>') *chr = ' '; else if (*chr == '|') *chr = ' '; } bool sampleNameIsEmpty(char *name) { if (name == NULL) return true; for (uint8_t i = 0; i < 22; i++) { if (name[i] != '\0') return false; } return true; } bool moduleNameIsEmpty(char *name) { if (name == NULL) return true; for (uint8_t i = 0; i < 20; i++) { if (name[i] != '\0') return false; } return true; } void updateWindowTitle(bool modified) { char titleTemp[128]; if (modified) modEntry->modified = true; else modEntry->modified = false; if (modEntry->head.moduleTitle[0] != '\0') { if (modified) { if (ptConfig.modDot) sprintf(titleTemp, "ProTracker 2 clone v%s - \"mod.%s\" (unsaved)", PROG_VER_STR, modEntry->head.moduleTitle); else sprintf(titleTemp, "ProTracker 2 clone v%s - \"%s.mod\" (unsaved)", PROG_VER_STR, modEntry->head.moduleTitle); } else { if (ptConfig.modDot) sprintf(titleTemp, "ProTracker 2 clone v%s - \"mod.%s\"", PROG_VER_STR, modEntry->head.moduleTitle); else sprintf(titleTemp, "ProTracker 2 clone v%s - \"%s.mod\"", PROG_VER_STR, modEntry->head.moduleTitle); } } else { if (modified) { if (ptConfig.modDot) sprintf(titleTemp, "ProTracker 2 clone v%s - \"mod.untitled\" (unsaved)", PROG_VER_STR); else sprintf(titleTemp, "ProTracker 2 clone v%s - \"untitled.mod\" (unsaved)", PROG_VER_STR); } else { if (ptConfig.modDot) sprintf(titleTemp, "ProTracker 2 clone v%s - \"mod.untitled\"", PROG_VER_STR); else sprintf(titleTemp, "ProTracker 2 clone v%s - \"untitled.mod\"", PROG_VER_STR); } } SDL_SetWindowTitle(window, titleTemp); } void recalcChordLength(void) { int8_t note; int32_t len; moduleSample_t *s; s = &modEntry->samples[editor.currSample]; if (editor.chordLengthMin) { note = MAX(MAX((editor.note1 == 36) ? -1 : editor.note1, (editor.note2 == 36) ? -1 : editor.note2), MAX((editor.note3 == 36) ? -1 : editor.note3, (editor.note4 == 36) ? -1 : editor.note4)); } else { note = MIN(MIN(editor.note1, editor.note2), MIN(editor.note3, editor.note4)); } if (note < 0 || note > 35) { editor.chordLength = 0; } else { assert(editor.tuningNote < 36); if (editor.tuningNote < 36) { len = (s->length * periodTable[(37 * s->fineTune) + note]) / periodTable[editor.tuningNote]; if (len > MAX_SAMPLE_LEN) len = MAX_SAMPLE_LEN; editor.chordLength = len & 0xFFFE; } } if (editor.ui.editOpScreenShown && editor.ui.editOpScreen == 3) editor.ui.updateLengthText = true; }