ft2-clone

Fasttracker 2 clone
Log | Files | Refs | README | LICENSE

commit 8af2e42736b61a36a0d54bede93a47a1bab35f5d
parent 6a594c824f0e29689297d1347faebaf451a1f382
Author: Olav Sørensen <olav.sorensen@live.no>
Date:   Thu,  1 Apr 2021 18:11:23 +0200

Pushed v1.45 code

- Fixed possible crash when starting the program on M1 Macs (thanks kode54)
- Fixed possible mouse cursor corruption when hovering over text boxes on Linux
- Fixed possibly buggy string operations
- Refactored some code that was doing unnecessary/wrong stuff
- Minor code cleanup
- Updated help text

Diffstat:
Msrc/ft2_audio.c | 26+++++++-------------------
Msrc/ft2_audioselector.c | 188++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
Msrc/ft2_config.c | 137++++++++++++++++++++++++++++++++++++++++---------------------------------------
Msrc/ft2_diskop.c | 183++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------------
Msrc/ft2_diskop.h | 2++
Msrc/ft2_events.c | 7++++---
Msrc/ft2_gui.c | 19++++++++++---------
Msrc/ft2_keyboard.c | 167+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------
Msrc/ft2_main.c | 28++++++++++++++++------------
Msrc/ft2_midi.c | 12+++++++-----
Msrc/ft2_module_loader.c | 31+++++++++++++++++++++++--------
Msrc/ft2_mouse.c | 7+++++--
Msrc/ft2_structs.h | 5++---
Msrc/ft2_sysreqs.c | 7+++++--
Msrc/ft2_textboxes.c | 2+-
Msrc/ft2_unicode.c | 19+++++++++++--------
Msrc/ft2_video.c | 10+++++++---
Msrc/helpdata/FT2.HLP | 4----
Msrc/helpdata/ft2_help_data.h | 76++++++++++++++++++++++++++++++++++------------------------------------------
19 files changed, 550 insertions(+), 380 deletions(-)

diff --git a/src/ft2_audio.c b/src/ft2_audio.c @@ -20,6 +20,11 @@ #include "mixer/ft2_silence_mix.h" // -------------------------------- +// hide POSIX warnings +#ifdef _MSC_VER +#pragma warning(disable: 4996) +#endif + #define INITIAL_DITHER_SEED 0x12345000 static int8_t pmpCountDiv, pmpChannels = 2; @@ -87,14 +92,7 @@ bool setNewAudioSettings(void) // only call this from the main input/video threa audio.currOutputDevice = NULL; } - const uint32_t stringLen = (uint32_t)strlen(audio.lastWorkingAudioDeviceName); - - audio.currOutputDevice = (char *)malloc(stringLen + 2); - if (audio.currOutputDevice != NULL) - { - strcpy(audio.currOutputDevice, audio.lastWorkingAudioDeviceName); - audio.currOutputDevice[stringLen + 1] = '\0'; // UTF-8 needs double null termination - } + audio.currOutputDevice = strdup(audio.lastWorkingAudioDeviceName); } // also update config audio radio buttons if we're on that screen at the moment @@ -1050,17 +1048,7 @@ static void setLastWorkingAudioDevName(void) } if (audio.currOutputDevice != NULL) - { - const uint32_t stringLen = (uint32_t)strlen(audio.currOutputDevice); - - audio.lastWorkingAudioDeviceName = (char *)malloc(stringLen + 2); - if (audio.lastWorkingAudioDeviceName != NULL) - { - if (stringLen > 0) - strcpy(audio.lastWorkingAudioDeviceName, audio.currOutputDevice); - audio.lastWorkingAudioDeviceName[stringLen + 1] = '\0'; // UTF-8 needs double null termination - } - } + audio.lastWorkingAudioDeviceName = strdup(audio.currOutputDevice); } bool setupAudio(bool showErrorMsg) diff --git a/src/ft2_audioselector.c b/src/ft2_audioselector.c @@ -13,53 +13,75 @@ #include "ft2_audioselector.h" #include "ft2_structs.h" -char *getAudioOutputDeviceFromConfig(void) +enum { + INPUT_DEVICE = 0, + OUTPUT_DEVICE = 1 +}; + #define MAX_DEV_STR_LEN 256 - char *devString = (char *)calloc(MAX_DEV_STR_LEN + 1, sizeof (char)); - if (devString == NULL) +// hide POSIX warnings +#ifdef _MSC_VER +#pragma warning(disable: 4996) +#endif + +static char *getReasonableAudioDevice(int32_t iscapture) // can and will return NULL +{ + int32_t numAudioDevs = SDL_GetNumAudioDevices(iscapture); + if (numAudioDevs == 0 || numAudioDevs > 1) + return NULL; // we don't know which audio output device is the default device + + const char *devName = SDL_GetAudioDeviceName(0, iscapture); + if (devName == NULL) return NULL; - FILE *f = UNICHAR_FOPEN(editor.audioDevConfigFileLocation, "r"); - if (f == NULL) + return strdup(devName); +} + +char *getAudioOutputDeviceFromConfig(void) +{ + bool audioDeviceRead = false; + char *devString = NULL; + + FILE *f = UNICHAR_FOPEN(editor.audioDevConfigFileLocationU, "r"); + if (f != NULL) { -#if defined(__APPLE__) - return NULL; // SDL doesn't return devices in any appreciable order, and device 0 is most certainly not guaranteed to be the current default device -#else - const char *devStringTmp = SDL_GetAudioDeviceName(0, false); - if (devStringTmp == NULL) + devString = (char *)malloc(MAX_DEV_STR_LEN+1); + if (devString == NULL) { - free(devString); - return NULL; + fclose(f); + return NULL; // out of memory } - const uint32_t devStringLen = (uint32_t)strlen(devStringTmp); + devString[0] = '\0'; + fgets(devString, MAX_DEV_STR_LEN, f); + fclose(f); + + const int32_t devStringLen = (int32_t)strlen(devString); if (devStringLen > 0) - strncpy(devString, devStringTmp, MAX_DEV_STR_LEN); - devString[devStringLen+1] = '\0'; // UTF-8 needs double null termination -#endif - } - else - { - if (fgets(devString, MAX_DEV_STR_LEN, f) == NULL) { - free(devString); - fclose(f); - return NULL; + if (devString[devStringLen-1] == '\n') + devString[devStringLen-1] = ' '; + + if (!(devStringLen == 1 && devString[0] == ' ')) // space only = no device + audioDeviceRead = true; } + } - const uint32_t devStringLen = (uint32_t)strlen(devString); - if (devString[devStringLen-1] == '\n') - devString[devStringLen-1] = '\0'; - devString[devStringLen+1] = '\0'; // UTF-8 needs double null termination + if (!audioDeviceRead) + { + if (devString != NULL) + free(devString); -#if defined(__APPLE__) - if (devString[0] == '\0') - return NULL; // macOS SDL2 locks up indefinitely if fed an empty string for device name -#endif + devString = getReasonableAudioDevice(OUTPUT_DEVICE); + } - fclose(f); + // SDL_OpenAudioDevice() doesn't seem to like an empty audio device string + if (devString != NULL && devString[0] == '\0') + { + free(devString); + return NULL; } return devString; @@ -67,50 +89,48 @@ char *getAudioOutputDeviceFromConfig(void) char *getAudioInputDeviceFromConfig(void) { -#define MAX_DEV_STR_LEN 256 + bool audioDeviceRead = false; + char *devString = NULL; - char *devString = (char *)calloc(MAX_DEV_STR_LEN + 1, sizeof (char)); - if (devString == NULL) - return NULL; - - FILE *f = UNICHAR_FOPEN(editor.audioDevConfigFileLocation, "r"); - if (f == NULL) + FILE *f = UNICHAR_FOPEN(editor.audioDevConfigFileLocationU, "r"); + if (f != NULL) { - const char *devStringTmp = SDL_GetAudioDeviceName(0, true); - if (devStringTmp == NULL) + devString = (char *)malloc(MAX_DEV_STR_LEN+1); + if (devString == NULL) { - free(devString); - return NULL; + fclose(f); + return NULL; // out of memory } - const uint32_t devStringLen = (uint32_t)strlen(devStringTmp); + devString[0] = '\0'; + fgets(devString, MAX_DEV_STR_LEN, f); // skip first line (we want the input device) + fgets(devString, MAX_DEV_STR_LEN, f); + fclose(f); + + const int32_t devStringLen = (int32_t)strlen(devString); if (devStringLen > 0) - strncpy(devString, devStringTmp, MAX_DEV_STR_LEN); - devString[devStringLen+1] = '\0'; // UTF-8 needs double null termination - } - else - { - if (fgets(devString, MAX_DEV_STR_LEN, f) == NULL) { - free(devString); - fclose(f); - return NULL; + if (devString[devStringLen-1] == '\n') + devString[devStringLen-1] = ' '; + + if (!(devStringLen == 1 && devString[0] == ' ')) // space only = no device + audioDeviceRead = true; } + } - // do it one more time (next line) - if (fgets(devString, MAX_DEV_STR_LEN, f) == NULL) - { + if (!audioDeviceRead) + { + if (devString != NULL) free(devString); - fclose(f); - return NULL; - } - const uint32_t devStringLen = (uint32_t)strlen(devString); - if (devString[devStringLen-1] == '\n') - devString[devStringLen-1] = '\0'; - devString[devStringLen+1] = '\0'; // UTF-8 needs double null termination + devString = getReasonableAudioDevice(INPUT_DEVICE); + } - fclose(f); + // SDL_OpenAudioDevice() doesn't seem to like an empty audio device string + if (devString != NULL && devString[0] == '\0') + { + free(devString); + return NULL; } return devString; @@ -118,15 +138,21 @@ char *getAudioInputDeviceFromConfig(void) bool saveAudioDevicesToConfig(const char *outputDevice, const char *inputDevice) { - FILE *f = UNICHAR_FOPEN(editor.audioDevConfigFileLocation, "w"); + FILE *f = UNICHAR_FOPEN(editor.audioDevConfigFileLocationU, "w"); if (f == NULL) return false; if (outputDevice != NULL) fputs(outputDevice, f); + else + fputc(' ', f); + fputc('\n', f); + if (inputDevice != NULL) fputs(inputDevice, f); + else + fputc(' ', f); fclose(f); return true; @@ -231,13 +257,14 @@ bool testAudioDeviceListsMouseDown(void) const uint32_t devStringLen = (uint32_t)strlen(devString); - audio.currOutputDevice = (char *)malloc(devStringLen + 2); + audio.currOutputDevice = (char *)malloc(devStringLen+1); if (audio.currOutputDevice == NULL) return true; + audio.currOutputDevice[0] = '\0'; + if (devStringLen > 0) strcpy(audio.currOutputDevice, devString); - audio.currOutputDevice[devStringLen+1] = '\0'; // UTF-8 needs double null termination if (!setNewAudioSettings()) okBox(0, "System message", "Couldn't open audio input device!"); @@ -263,13 +290,14 @@ bool testAudioDeviceListsMouseDown(void) const uint32_t devStringLen = (uint32_t)strlen(devString); - audio.currInputDevice = (char *)malloc(devStringLen + 2); + audio.currInputDevice = (char *)malloc(devStringLen+1); if (audio.currInputDevice == NULL) return true; + audio.currInputDevice[0] = '\0'; + if (devStringLen > 0) strcpy(audio.currInputDevice, devString); - audio.currInputDevice[devStringLen+1] = '\0'; // UTF-8 needs double null termination drawAudioInputList(); } @@ -303,10 +331,10 @@ void freeAudioDeviceLists(void) void freeAudioDeviceSelectorBuffers(void) { - if (editor.audioDevConfigFileLocation != NULL) + if (editor.audioDevConfigFileLocationU != NULL) { - free(editor.audioDevConfigFileLocation); - editor.audioDevConfigFileLocation = NULL; + free(editor.audioDevConfigFileLocationU); + editor.audioDevConfigFileLocationU = NULL; } if (audio.currOutputDevice != NULL) @@ -352,14 +380,12 @@ void setToDefaultAudioOutputDevice(void) audio.currOutputDevice = NULL; } - audio.currOutputDevice = (char *)malloc(stringLen + 2); + audio.currOutputDevice = (char *)malloc(stringLen + 1); if (audio.currOutputDevice == NULL) return; if (stringLen > 0) strcpy(audio.currOutputDevice, devString); - - audio.currOutputDevice[stringLen+1] = '\0'; // UTF-8 needs double null termination } void setToDefaultAudioInputDevice(void) @@ -384,14 +410,12 @@ void setToDefaultAudioInputDevice(void) audio.currInputDevice = NULL; } - audio.currInputDevice = (char *)malloc(stringLen + 2); + audio.currInputDevice = (char *)malloc(stringLen + 1); if (audio.currInputDevice == NULL) return; if (stringLen > 0) strcpy(audio.currInputDevice, devString); - - audio.currInputDevice[stringLen+1] = '\0'; // UTF-8 needs double null termination } void rescanAudioDevices(void) @@ -417,14 +441,12 @@ void rescanAudioDevices(void) const uint32_t stringLen = (uint32_t)strlen(deviceName); - audio.outputDeviceNames[i] = (char *)malloc(stringLen + 2); + audio.outputDeviceNames[i] = (char *)malloc(stringLen + 1); if (audio.outputDeviceNames[i] == NULL) break; if (stringLen > 0) strcpy(audio.outputDeviceNames[i], deviceName); - - audio.outputDeviceNames[i][stringLen+1] = '\0'; // UTF-8 needs double null termination } // GET AUDIO INPUT DEVICES @@ -444,14 +466,12 @@ void rescanAudioDevices(void) const uint32_t stringLen = (uint32_t)strlen(deviceName); - audio.inputDeviceNames[i] = (char *)malloc(stringLen + 2); + audio.inputDeviceNames[i] = (char *)malloc(stringLen + 1); if (audio.inputDeviceNames[i] == NULL) break; if (stringLen > 0) strcpy(audio.inputDeviceNames[i], deviceName); - - audio.inputDeviceNames[i][stringLen+1] = '\0'; // UTF-8 needs double null termination } setScrollBarEnd(SB_AUDIO_OUTPUT_SCROLL, audio.outputDeviceNum); diff --git a/src/ft2_config.c b/src/ft2_config.c @@ -264,7 +264,7 @@ bool loadConfig(bool showErrorFlag) } #endif - if (editor.configFileLocation == NULL) + if (editor.configFileLocationU == NULL) { if (showErrorFlag) okBox(0, "System message", "Error opening config file for reading!"); @@ -272,7 +272,7 @@ bool loadConfig(bool showErrorFlag) return false; } - FILE *f = UNICHAR_FOPEN(editor.configFileLocation, "rb"); + FILE *f = UNICHAR_FOPEN(editor.configFileLocationU, "rb"); if (f == NULL) { if (showErrorFlag) @@ -353,7 +353,7 @@ void loadConfig2(void) // called by "Load config" button bool saveConfig(bool showErrorFlag) { - if (editor.configFileLocation == NULL) + if (editor.configFileLocationU == NULL) { if (showErrorFlag) okBox(0, "System message", "General I/O error during saving! Is the file in use?"); @@ -366,7 +366,7 @@ bool saveConfig(bool showErrorFlag) saveMidiInputDeviceToConfig(); #endif - FILE *f = UNICHAR_FOPEN(editor.configFileLocation, "wb"); + FILE *f = UNICHAR_FOPEN(editor.configFileLocationU, "wb"); if (f == NULL) { if (showErrorFlag) @@ -410,14 +410,14 @@ void saveConfig2(void) // called by "Save config" button saveConfig(CONFIG_SHOW_ERRORS); } -static UNICHAR *getFullAudDevConfigPath(void) // kinda hackish +static UNICHAR *getFullAudDevConfigPathU(void) // kinda hackish { int32_t audiodevDotIniStrLen, ft2DotCfgStrLen; - if (editor.configFileLocation == NULL) + if (editor.configFileLocationU == NULL) return NULL; - const int32_t ft2ConfPathLen = (int32_t)UNICHAR_STRLEN(editor.configFileLocation); + const int32_t ft2ConfPathLen = (int32_t)UNICHAR_STRLEN(editor.configFileLocationU); #ifdef _WIN32 audiodevDotIniStrLen = (int32_t)UNICHAR_STRLEN(L"audiodev.ini"); @@ -427,31 +427,29 @@ static UNICHAR *getFullAudDevConfigPath(void) // kinda hackish ft2DotCfgStrLen = (int32_t)UNICHAR_STRLEN("FT2.CFG"); #endif - UNICHAR *filePath = (UNICHAR *)calloc(ft2ConfPathLen + audiodevDotIniStrLen + 2, sizeof (UNICHAR)); + UNICHAR *filePathU = (UNICHAR *)malloc((ft2ConfPathLen + audiodevDotIniStrLen + 1) * sizeof (UNICHAR)); + filePathU[0] = 0; - UNICHAR_STRCPY(filePath, editor.configFileLocation); - - const int32_t stringOffset = ft2ConfPathLen - ft2DotCfgStrLen; - filePath[stringOffset+0] = '\0'; - filePath[stringOffset+1] = '\0'; + UNICHAR_STRCPY(filePathU, editor.configFileLocationU); + filePathU[ft2ConfPathLen-ft2DotCfgStrLen] = 0; #ifdef _WIN32 - UNICHAR_STRCAT(filePath, L"audiodev.ini"); + UNICHAR_STRCAT(filePathU, L"audiodev.ini"); #else - UNICHAR_STRCAT(filePath, "audiodev.ini"); + UNICHAR_STRCAT(filePathU, "audiodev.ini"); #endif - return filePath; + return filePathU; } -static UNICHAR *getFullMidiDevConfigPath(void) // kinda hackish +static UNICHAR *getFullMidiDevConfigPathU(void) // kinda hackish { int32_t mididevDotIniStrLen, ft2DotCfgStrLen; - if (editor.configFileLocation == NULL) + if (editor.configFileLocationU == NULL) return NULL; - const int32_t ft2ConfPathLen = (int32_t)UNICHAR_STRLEN(editor.configFileLocation); + const int32_t ft2ConfPathLen = (int32_t)UNICHAR_STRLEN(editor.configFileLocationU); #ifdef _WIN32 mididevDotIniStrLen = (int32_t)UNICHAR_STRLEN(L"mididev.ini"); @@ -461,21 +459,19 @@ static UNICHAR *getFullMidiDevConfigPath(void) // kinda hackish ft2DotCfgStrLen = (int32_t)UNICHAR_STRLEN("FT2.CFG"); #endif - UNICHAR *filePath = (UNICHAR *)calloc(ft2ConfPathLen + mididevDotIniStrLen + 2, sizeof (UNICHAR)); - - UNICHAR_STRCPY(filePath, editor.configFileLocation); + UNICHAR *filePathU = (UNICHAR *)malloc((ft2ConfPathLen + mididevDotIniStrLen + 1) * sizeof (UNICHAR)); + filePathU[0] = 0; - const int32_t stringOffset = ft2ConfPathLen - ft2DotCfgStrLen; - filePath[stringOffset+0] = '\0'; - filePath[stringOffset+1] = '\0'; + UNICHAR_STRCPY(filePathU, editor.configFileLocationU); + filePathU[ft2ConfPathLen-ft2DotCfgStrLen] = 0; #ifdef _WIN32 - UNICHAR_STRCAT(filePath, L"mididev.ini"); + UNICHAR_STRCAT(filePathU, L"mididev.ini"); #else - UNICHAR_STRCAT(filePath, "mididev.ini"); + UNICHAR_STRCAT(filePathU, "mididev.ini"); #endif - return filePath; + return filePathU; } static void setConfigFileLocation(void) // kinda hackish @@ -484,41 +480,44 @@ static void setConfigFileLocation(void) // kinda hackish #ifdef _WIN32 int32_t ft2DotCfgStrLen = (int32_t)UNICHAR_STRLEN(L"FT2.CFG"); - UNICHAR *oldPath = (UNICHAR *)calloc(PATH_MAX + 8 + 2, sizeof (UNICHAR)); - UNICHAR *tmpPath = (UNICHAR *)calloc(PATH_MAX + 8 + 2, sizeof (UNICHAR)); - editor.configFileLocation = (UNICHAR *)calloc(PATH_MAX + ft2DotCfgStrLen + 2, sizeof (UNICHAR)); + UNICHAR *oldPathU = (UNICHAR *)malloc((PATH_MAX + 8 + 1) * sizeof (UNICHAR)); + UNICHAR *tmpPathU = (UNICHAR *)malloc((PATH_MAX + 8 + 1) * sizeof (UNICHAR)); + editor.configFileLocationU = (UNICHAR *)malloc((PATH_MAX + ft2DotCfgStrLen + 1) * sizeof (UNICHAR)); - if (oldPath == NULL || tmpPath == NULL || editor.configFileLocation == NULL) + if (oldPathU == NULL || tmpPathU == NULL || editor.configFileLocationU == NULL) { - if (oldPath != NULL) free(oldPath); - if (tmpPath != NULL) free(tmpPath); - if (editor.configFileLocation != NULL) free(editor.configFileLocation); + if (oldPathU != NULL) free(oldPathU); + if (tmpPathU != NULL) free(tmpPathU); + if (editor.configFileLocationU != NULL) free(editor.configFileLocationU); - editor.configFileLocation = NULL; + editor.configFileLocationU = NULL; showErrorMsgBox("Error: Couldn't set config file location. You can't load/save the config!"); return; } - if (GetCurrentDirectoryW(PATH_MAX - ft2DotCfgStrLen - 1, oldPath) == 0) + oldPathU[0] = 0; + tmpPathU[0] = 0; + + if (GetCurrentDirectoryW(PATH_MAX - ft2DotCfgStrLen - 1, oldPathU) == 0) { - free(oldPath); - free(tmpPath); - free(editor.configFileLocation); + free(oldPathU); + free(tmpPathU); + free(editor.configFileLocationU); - editor.configFileLocation = NULL; + editor.configFileLocationU = NULL; showErrorMsgBox("Error: Couldn't set config file location. You can't load/save the config!"); return; } - UNICHAR_STRCPY(editor.configFileLocation, oldPath); + UNICHAR_STRCPY(editor.configFileLocationU, oldPathU); FILE *f = fopen("FT2.CFG", "rb"); if (f == NULL) // FT2.CFG not found in current dir, try default config dir { - int32_t result = SHGetFolderPathW(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, tmpPath); + int32_t result = SHGetFolderPathW(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, tmpPathU); if (result == S_OK) { - if (SetCurrentDirectoryW(tmpPath) != 0) + if (SetCurrentDirectoryW(tmpPathU) != 0) { result = chdir("FT2 clone"); if (result != 0) @@ -528,7 +527,7 @@ static void setConfigFileLocation(void) // kinda hackish } if (result == 0) - GetCurrentDirectoryW(PATH_MAX - ft2DotCfgStrLen - 1, editor.configFileLocation); // we can, set it + GetCurrentDirectoryW(PATH_MAX - ft2DotCfgStrLen - 1, editor.configFileLocationU); // we can, set it } } } @@ -537,27 +536,29 @@ static void setConfigFileLocation(void) // kinda hackish fclose(f); } - free(tmpPath); - SetCurrentDirectoryW(oldPath); - free(oldPath); + free(tmpPathU); + SetCurrentDirectoryW(oldPathU); + free(oldPathU); - UNICHAR_STRCAT(editor.configFileLocation, L"\\FT2.CFG"); + UNICHAR_STRCAT(editor.configFileLocationU, L"\\FT2.CFG"); // OS X / macOS #elif defined __APPLE__ int32_t ft2DotCfgStrLen = (int32_t)UNICHAR_STRLEN("FT2.CFG"); - editor.configFileLocation = (UNICHAR *)calloc(PATH_MAX + ft2DotCfgStrLen + 2, sizeof (UNICHAR)); - if (editor.configFileLocation == NULL) + editor.configFileLocationU = (UNICHAR *)malloc((PATH_MAX + ft2DotCfgStrLen + 1) * sizeof (UNICHAR)); + if (editor.configFileLocationU == NULL) { showErrorMsgBox("Error: Couldn't set config file location. You can't load/save the config!"); return; } - if (getcwd(editor.configFileLocation, PATH_MAX - ft2DotCfgStrLen - 1) == NULL) + editor.configFileLocationU[0] = 0; + + if (getcwd(editor.configFileLocationU, PATH_MAX - ft2DotCfgStrLen - 1) == NULL) { - free(editor.configFileLocation); - editor.configFileLocation = NULL; + free(editor.configFileLocationU); + editor.configFileLocationU = NULL; showErrorMsgBox("Error: Couldn't set config file location. You can't load/save the config!"); return; } @@ -578,7 +579,7 @@ static void setConfigFileLocation(void) // kinda hackish } if (result == 0) - getcwd(editor.configFileLocation, PATH_MAX - ft2DotCfgStrLen - 1); + getcwd(editor.configFileLocationU, PATH_MAX - ft2DotCfgStrLen - 1); } } } @@ -587,23 +588,25 @@ static void setConfigFileLocation(void) // kinda hackish fclose(f); } - strcat(editor.configFileLocation, "/FT2.CFG"); + strcat(editor.configFileLocationU, "/FT2.CFG"); // Linux etc #else int32_t ft2DotCfgStrLen = (int32_t)UNICHAR_STRLEN("FT2.CFG"); - editor.configFileLocation = (UNICHAR *)calloc(PATH_MAX + ft2DotCfgStrLen + 2, sizeof (UNICHAR)); - if (editor.configFileLocation == NULL) + editor.configFileLocationU = (UNICHAR *)malloc((PATH_MAX + ft2DotCfgStrLen + 1) * sizeof (UNICHAR)); + if (editor.configFileLocationU == NULL) { showErrorMsgBox("Error: Couldn't set config file location. You can't load/save the config!"); return; } - if (getcwd(editor.configFileLocation, PATH_MAX - ft2DotCfgStrLen - 1) == NULL) + editor.configFileLocationU[0] = 0; + + if (getcwd(editor.configFileLocationU, PATH_MAX - ft2DotCfgStrLen - 1) == NULL) { - free(editor.configFileLocation); - editor.configFileLocation = NULL; + free(editor.configFileLocationU); + editor.configFileLocationU = NULL; showErrorMsgBox("Error: Couldn't set config file location. You can't load/save the config!"); return; } @@ -632,7 +635,7 @@ static void setConfigFileLocation(void) // kinda hackish } if (result == 0) - getcwd(editor.configFileLocation, PATH_MAX - ft2DotCfgStrLen - 1); + getcwd(editor.configFileLocationU, PATH_MAX - ft2DotCfgStrLen - 1); } } else @@ -640,23 +643,23 @@ static void setConfigFileLocation(void) // kinda hackish fclose(f); } - strcat(editor.configFileLocation, "/FT2.CFG"); + strcat(editor.configFileLocationU, "/FT2.CFG"); #endif - editor.midiConfigFileLocation = getFullMidiDevConfigPath(); - editor.audioDevConfigFileLocation = getFullAudDevConfigPath(); + editor.midiConfigFileLocationU = getFullMidiDevConfigPathU(); + editor.audioDevConfigFileLocationU = getFullAudDevConfigPathU(); } void loadConfigOrSetDefaults(void) { setConfigFileLocation(); - if (editor.configFileLocation == NULL) + if (editor.configFileLocationU == NULL) { setDefaultConfigSettings(); return; } - FILE *f = UNICHAR_FOPEN(editor.configFileLocation, "rb"); + FILE *f = UNICHAR_FOPEN(editor.configFileLocationU, "rb"); if (f == NULL) { setDefaultConfigSettings(); diff --git a/src/ft2_diskop.c b/src/ft2_diskop.c @@ -72,7 +72,7 @@ typedef struct DirRec int32_t filesize; } DirRec; -static char FReq_SysReqText[196], *FReq_FileName, *FReq_NameTemp; +static char FReq_SysReqText[256], *FReq_FileName, *FReq_NameTemp; static char *modTmpFName, *insTmpFName, *smpTmpFName, *patTmpFName, *trkTmpFName; static char *modTmpFNameUTF8; // for window title static uint8_t FReq_Item; @@ -84,6 +84,18 @@ static SDL_Thread *thread; static void setDiskOpItem(uint8_t item); +bool setupExecutablePath(void) +{ + editor.binaryPathU = (UNICHAR *)malloc((PATH_MAX + 1) * sizeof (UNICHAR)); + if (editor.binaryPathU == NULL) + return false; + + editor.binaryPathU[0] = 0; + UNICHAR_GETCWD(editor.binaryPathU, PATH_MAX); + + return true; +} + int32_t getFileSize(UNICHAR *fileNameU) // returning -1 = filesize over 2GB { int64_t fSize; @@ -173,56 +185,70 @@ static void setupInitialPaths(void) #ifdef _WIN32 if (config.modulesPath[0] != '\0') + { MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, config.modulesPath, -1, FReq_ModCurPathU, 80); + FReq_ModCurPathU[80] = 0; + } if (config.instrPath[0] != '\0') { MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, config.instrPath, -1, FReq_InsCurPathU, 80); + FReq_InsCurPathU[80] = 0; insPathSet = true; } if (config.samplesPath[0] != '\0') { MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, config.samplesPath, -1, FReq_SmpCurPathU, 80); + FReq_SmpCurPathU[80] = 0; smpPathSet = true; } if (config.patternsPath[0] != '\0') { MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, config.patternsPath, -1, FReq_PatCurPathU, 80); + FReq_PatCurPathU[80] = 0; patPathSet = true; } if (config.tracksPath[0] != '\0') { MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, config.tracksPath, -1, FReq_TrkCurPathU, 80); + FReq_TrkCurPathU[80] = 0; trkPathSet = true; } #else if (config.modulesPath[0] != '\0') + { strncpy(FReq_ModCurPathU, config.modulesPath, 80); + FReq_ModCurPathU[80] = 0; + } if (config.instrPath[0] != '\0') { strncpy(FReq_InsCurPathU, config.instrPath, 80); + FReq_InsCurPathU[80] = 0; insPathSet = true; } if (config.samplesPath[0] != '\0') { strncpy(FReq_SmpCurPathU, config.samplesPath, 80); + FReq_SmpCurPathU[80] = 0; smpPathSet = true; } if (config.patternsPath[0] != '\0') { strncpy(FReq_PatCurPathU, config.patternsPath, 80); + FReq_PatCurPathU[80] = 0; patPathSet = true; } if (config.tracksPath[0] != '\0') { strncpy(FReq_TrkCurPathU, config.tracksPath, 80); + FReq_TrkCurPathU[80] = 0; trkPathSet = true; } #endif @@ -277,28 +303,42 @@ void freeDiskOp(void) bool setupDiskOp(void) { - modTmpFName = (char *)calloc(PATH_MAX + 1, sizeof (char)); - insTmpFName = (char *)calloc(PATH_MAX + 1, sizeof (char)); - smpTmpFName = (char *)calloc(PATH_MAX + 1, sizeof (char)); - patTmpFName = (char *)calloc(PATH_MAX + 1, sizeof (char)); - trkTmpFName = (char *)calloc(PATH_MAX + 1, sizeof (char)); - FReq_NameTemp = (char *)calloc(PATH_MAX + 1, sizeof (char)); - FReq_ModCurPathU = (UNICHAR *)calloc(PATH_MAX + 2, sizeof (UNICHAR)); - FReq_InsCurPathU = (UNICHAR *)calloc(PATH_MAX + 2, sizeof (UNICHAR)); - FReq_SmpCurPathU = (UNICHAR *)calloc(PATH_MAX + 2, sizeof (UNICHAR)); - FReq_PatCurPathU = (UNICHAR *)calloc(PATH_MAX + 2, sizeof (UNICHAR)); - FReq_TrkCurPathU = (UNICHAR *)calloc(PATH_MAX + 2, sizeof (UNICHAR)); - - if (modTmpFName == NULL || insTmpFName == NULL || smpTmpFName == NULL || patTmpFName == NULL || - trkTmpFName == NULL || FReq_NameTemp == NULL || FReq_ModCurPathU == NULL || - FReq_InsCurPathU == NULL || FReq_SmpCurPathU == NULL || FReq_PatCurPathU == NULL || - FReq_TrkCurPathU == NULL) + modTmpFName = (char *)malloc((PATH_MAX + 1) * sizeof (char)); + insTmpFName = (char *)malloc((PATH_MAX + 1) * sizeof (char)); + smpTmpFName = (char *)malloc((PATH_MAX + 1) * sizeof (char)); + patTmpFName = (char *)malloc((PATH_MAX + 1) * sizeof (char)); + trkTmpFName = (char *)malloc((PATH_MAX + 1) * sizeof (char)); + FReq_NameTemp = (char *)malloc((PATH_MAX + 1) * sizeof (char)); + + FReq_ModCurPathU = (UNICHAR *)malloc((PATH_MAX + 1) * sizeof (UNICHAR)); + FReq_InsCurPathU = (UNICHAR *)malloc((PATH_MAX + 1) * sizeof (UNICHAR)); + FReq_SmpCurPathU = (UNICHAR *)malloc((PATH_MAX + 1) * sizeof (UNICHAR)); + FReq_PatCurPathU = (UNICHAR *)malloc((PATH_MAX + 1) * sizeof (UNICHAR)); + FReq_TrkCurPathU = (UNICHAR *)malloc((PATH_MAX + 1) * sizeof (UNICHAR)); + + if (modTmpFName == NULL || insTmpFName == NULL || smpTmpFName == NULL || + patTmpFName == NULL || trkTmpFName == NULL || FReq_NameTemp == NULL || + FReq_ModCurPathU == NULL || FReq_InsCurPathU == NULL || FReq_SmpCurPathU == NULL || + FReq_PatCurPathU == NULL || FReq_TrkCurPathU == NULL) { // allocated memory is free'd lateron showErrorMsgBox("Not enough memory!"); return false; } + // clear first entry of strings + modTmpFName[0] = '\0'; + insTmpFName[0] = '\0'; + smpTmpFName[0] = '\0'; + patTmpFName[0] = '\0'; + trkTmpFName[0] = '\0'; + FReq_NameTemp[0] = '\0'; + FReq_ModCurPathU[0] = 0; + FReq_InsCurPathU[0] = 0; + FReq_SmpCurPathU[0] = 0; + FReq_PatCurPathU[0] = 0; + FReq_TrkCurPathU[0] = 0; + strcpy(modTmpFName, "untitled.xm"); strcpy(insTmpFName, "untitled.xi"); strcpy(smpTmpFName, "untitled.wav"); @@ -602,7 +642,7 @@ void diskOpSetFilename(uint8_t type, UNICHAR *pathU) char *filename = getFilenameFromPath(ansiPath); uint32_t filenameLen = (uint32_t)strlen(filename); - if (filenameLen > PATH_MAX-1) + if (filenameLen > PATH_MAX) { free(ansiPath); return; // filename is too long, don't bother to copy it over @@ -693,9 +733,9 @@ static void openFile(UNICHAR *filenameU, bool songModifiedCheck) { if (songModifiedCheck && song.isModified) { - // remove file selection + // remove file selection before okBox() opens up FReq_EntrySelected = -1; - diskOp_DrawDirectory(); + diskOp_DrawFilelist(); if (okBox(2, "System request", "You have unsaved changes in your song. Load new song and lose all changes?") != 1) return; @@ -758,8 +798,6 @@ void changeFilenameExt(char *name, char *ext, int32_t nameMaxLen) void diskOpChangeFilenameExt(char *ext) { changeFilenameExt(FReq_FileName, ext, PATH_MAX); - if (ui.diskOpShown) - diskOp_DrawDirectory(); } void trimEntryName(char *name, bool isDir) @@ -1011,7 +1049,7 @@ static void fileListPressed(int32_t index) // remove file selection FReq_EntrySelected = -1; - diskOp_DrawDirectory(); + diskOp_DrawFilelist(); DirRec *dirEntry = &FReq_Buffer[entryIndex]; switch (mode) @@ -1077,15 +1115,16 @@ static void fileListPressed(int32_t index) if (nameTmp == NULL) break; - strncpy(FReq_NameTemp, nameTmp, PATH_MAX - 1); + strncpy(FReq_NameTemp, nameTmp, PATH_MAX); + FReq_NameTemp[PATH_MAX] = '\0'; free(nameTmp); // in case of UTF8 -> CP437 encoding failure, there can be question marks. Remove them... removeQuestionmarksFromString(FReq_NameTemp); - if (inputBox(1, dirEntry->isDir ? "Enter new directory name:" : "Enter new filename:", FReq_NameTemp, PATH_MAX - 1) == 1) + if (inputBox(1, dirEntry->isDir ? "Enter new directory name:" : "Enter new filename:", FReq_NameTemp, PATH_MAX) == 1) { - if ((FReq_NameTemp == NULL) || (FReq_NameTemp[0] == '\0')) + if (FReq_NameTemp == NULL || FReq_NameTemp[0] == '\0') { okBox(0, "System message", "New name can't be empty!"); break; @@ -1120,7 +1159,7 @@ bool testDiskOpMouseDown(bool mouseHeldDlown) if (max > DISKOP_ENTRY_NUM) // needed kludge when mouse-scrolling max = DISKOP_ENTRY_NUM; - if (!mouseHeldDlown) + if (!mouseHeldDlown) // select file { FReq_EntrySelected = -1; @@ -1130,7 +1169,7 @@ bool testDiskOpMouseDown(bool mouseHeldDlown) if (tmpEntry >= 0 && tmpEntry < max) { FReq_EntrySelected = tmpEntry; - diskOp_DrawDirectory(); + diskOp_DrawFilelist(); } mouse.lastUsedObjectType = OBJECT_DISKOPLIST; @@ -1161,7 +1200,7 @@ bool testDiskOpMouseDown(bool mouseHeldDlown) if (mouse.x < 169 || mouse.x > 331 || mouse.y < 4 || tmpEntry < 0 || tmpEntry >= max) { FReq_EntrySelected = -1; - diskOp_DrawDirectory(); + diskOp_DrawFilelist(); return true; } @@ -1169,7 +1208,7 @@ bool testDiskOpMouseDown(bool mouseHeldDlown) if (tmpEntry != FReq_EntrySelected) { FReq_EntrySelected = tmpEntry; - diskOp_DrawDirectory(); + diskOp_DrawFilelist(); } return true; @@ -1183,7 +1222,7 @@ void testDiskOpMouseRelease(void) fileListPressed((mouse.y - 4) / (FONT1_CHAR_H + 1)); FReq_EntrySelected = -1; - diskOp_DrawDirectory(); + diskOp_DrawFilelist(); } } @@ -1537,7 +1576,7 @@ static char *ach(int32_t rad) // used for sortDirectory() return NULL; } - char *p = (char *)malloc(nameLen + 2); + char *p = (char *)malloc(nameLen+1+1); if (p == NULL) { free(name); @@ -1701,6 +1740,9 @@ static void displayCurrPath(void) { fillRect(4, 145, 162, 10, PAL_DESKTOP); + if (FReq_CurPathU == NULL) + return; + const uint32_t pathLen = (uint32_t)UNICHAR_STRLEN(FReq_CurPathU); if (pathLen == 0) return; @@ -1722,11 +1764,14 @@ static void displayCurrPath(void) { // path doesn't fit, print drive + ".." + last directory - memset(FReq_NameTemp, 0, PATH_MAX + 1); #ifdef _WIN32 - strncpy(FReq_NameTemp, p, 3); + memcpy(FReq_NameTemp, p, 3); // get drive (f.ex. C:\) + FReq_NameTemp[3] = '\0'; + strcat(FReq_NameTemp, ".\001"); // special character in font + FReq_NameTemp[5] = '\0'; #else + FReq_NameTemp[0] = '\0'; strcpy(FReq_NameTemp, "/"); strcat(FReq_NameTemp, ".."); #endif @@ -1735,7 +1780,7 @@ static void displayCurrPath(void) if (delimiter != NULL) { #ifdef _WIN32 - strcat(FReq_NameTemp, delimiter + 1); + strcat(FReq_NameTemp, delimiter+1); #else strcat(FReq_NameTemp, delimiter); #endif @@ -1749,9 +1794,9 @@ static void displayCurrPath(void) p = FReq_NameTemp; while (j >= 6 && textWidth(p) >= 162) { - p[j - 2] = '.'; - p[j - 1] = '.'; - p[j - 0] = '\0'; + p[j-2] = '.'; + p[j-1] = '.'; + p[j-0] = '\0'; j--; } } @@ -1762,25 +1807,20 @@ static void displayCurrPath(void) free(asciiPath); } -void diskOp_DrawDirectory(void) +void diskOp_DrawFilelist(void) { - clearRect(FILENAME_TEXT_X - 1, 4, 162, 164); - drawTextBox(TB_DISKOP_FILENAME); + clearRect(FILENAME_TEXT_X-1, 4, 162, 164); + if (FReq_FileCount == 0) + return; + + // draw "selected file" rectangle if (FReq_EntrySelected != -1) { const uint16_t y = 4 + (uint16_t)((FONT1_CHAR_H + 1) * FReq_EntrySelected); fillRect(FILENAME_TEXT_X - 1, y, 162, FONT1_CHAR_H, PAL_PATTEXT); } - displayCurrPath(); -#ifdef _WIN32 - setupDiskOpDrives(); -#endif - - if (FReq_FileCount == 0) - return; - for (uint16_t i = 0; i < DISKOP_ENTRY_NUM; i++) { const int32_t bufEntry = FReq_DirPos + i; @@ -1817,9 +1857,21 @@ void diskOp_DrawDirectory(void) if (!FReq_Buffer[bufEntry].isDir) printFormattedFilesize(FILESIZE_TEXT_X, y, bufEntry); } +} + +void diskOp_DrawDirectory(void) +{ + drawTextBox(TB_DISKOP_FILENAME); + + displayCurrPath(); +#ifdef _WIN32 + setupDiskOpDrives(); +#endif - setScrollBarPos(SB_DISKOP_LIST, FReq_DirPos, true); setScrollBarEnd(SB_DISKOP_LIST, FReq_FileCount); + setScrollBarPos(SB_DISKOP_LIST, FReq_DirPos, false); + + diskOp_DrawFilelist(); } static DirRec *bufferCreateEmptyDir(void) // special case: creates a dir entry with a ".." directory @@ -2035,7 +2087,7 @@ static void setDiskOpItem(uint8_t item) // FReq_ModCurPathU is always set at this point FReq_CurPathU = FReq_ModCurPathU; - if (FReq_CurPathU != NULL) + if (FReq_CurPathU != NULL && FReq_CurPathU[0] != '\0') UNICHAR_CHDIR(FReq_CurPathU); } break; @@ -2044,7 +2096,7 @@ static void setDiskOpItem(uint8_t item) { FReq_FileName = insTmpFName; - if (!insPathSet) + if (!insPathSet && FReq_CurPathU != NULL && FReq_CurPathU[0] != '\0') { UNICHAR_STRCPY(FReq_InsCurPathU, FReq_CurPathU); insPathSet = true; @@ -2060,7 +2112,7 @@ static void setDiskOpItem(uint8_t item) { FReq_FileName = smpTmpFName; - if (!smpPathSet) + if (!smpPathSet && FReq_CurPathU != NULL && FReq_CurPathU[0] != '\0') { UNICHAR_STRCPY(FReq_SmpCurPathU, FReq_CurPathU); smpPathSet = true; @@ -2076,7 +2128,7 @@ static void setDiskOpItem(uint8_t item) { FReq_FileName = patTmpFName; - if (!patPathSet) + if (!patPathSet && FReq_CurPathU != NULL && FReq_CurPathU[0] != '\0') { UNICHAR_STRCPY(FReq_PatCurPathU, FReq_CurPathU); patPathSet = true; @@ -2092,7 +2144,7 @@ static void setDiskOpItem(uint8_t item) { FReq_FileName = trkTmpFName; - if (!trkPathSet) + if (!trkPathSet && FReq_CurPathU != NULL && FReq_CurPathU[0] != '\0') { UNICHAR_STRCPY(FReq_TrkCurPathU, FReq_CurPathU); trkPathSet = true; @@ -2105,15 +2157,13 @@ static void setDiskOpItem(uint8_t item) break; } - const int32_t pathLen = (int32_t)UNICHAR_STRLEN(FReq_CurPathU); - if (pathLen == 0 && FReq_ModCurPathU[0] != '\0') + if (FReq_CurPathU != NULL && FReq_ModCurPathU != NULL) { - memset(FReq_CurPathU, 0, (PATH_MAX + 2) * sizeof (UNICHAR)); - UNICHAR_STRCPY(FReq_CurPathU, FReq_ModCurPathU); + if (FReq_CurPathU[0] == '\0' && FReq_ModCurPathU[0] != '\0') + UNICHAR_STRCPY(FReq_CurPathU, FReq_ModCurPathU); } textBoxes[TB_DISKOP_FILENAME].textPtr = FReq_FileName; - FReq_ShowAllFiles = false; if (ui.diskOpShown) @@ -2199,14 +2249,15 @@ void showDiskOpScreen(void) assert(FReq_ModCurPathU != NULL); // first test if we can change the dir to the one stored in the config (if present) - if (UNICHAR_STRLEN(FReq_ModCurPathU) == 0 || UNICHAR_CHDIR(FReq_ModCurPathU) != 0) + if (FReq_ModCurPathU[0] == '\0' || UNICHAR_CHDIR(FReq_ModCurPathU) != 0) { // nope, couldn't do that, set Disk Op. path to user/home directory #ifdef _WIN32 SHGetFolderPathW(NULL, CSIDL_PROFILE, NULL, 0, FReq_ModCurPathU); #else - if (getenv("HOME") != NULL) - UNICHAR_STRCPY(FReq_ModCurPathU, getenv("HOME")); + char *home = getenv("HOME"); + if (home != NULL) + UNICHAR_STRCPY(FReq_ModCurPathU, home); #endif UNICHAR_CHDIR(FReq_ModCurPathU); } @@ -2285,7 +2336,7 @@ void sbDiskOpSetPos(uint32_t pos) if ((int32_t)pos != FReq_DirPos && FReq_FileCount > DISKOP_ENTRY_NUM) { FReq_DirPos = (int32_t)pos; - diskOp_DrawDirectory(); + diskOp_DrawFilelist(); } } @@ -2345,7 +2396,7 @@ void pbDiskOpRename(void) void pbDiskOpMakeDir(void) { FReq_NameTemp[0] = '\0'; - if (inputBox(1, "Enter directory name:", FReq_NameTemp, PATH_MAX - 1) == 1) + if (inputBox(1, "Enter directory name:", FReq_NameTemp, PATH_MAX) == 1) { if (FReq_NameTemp[0] == '\0') { @@ -2371,7 +2422,7 @@ void pbDiskOpRefresh(void) void pbDiskOpSetPath(void) { FReq_NameTemp[0] = '\0'; - if (inputBox(1, "Enter new directory path:", FReq_NameTemp, PATH_MAX - 1) == 1) + if (inputBox(1, "Enter new directory path:", FReq_NameTemp, PATH_MAX) == 1) { if (FReq_NameTemp[0] == '\0') { diff --git a/src/ft2_diskop.h b/src/ft2_diskop.h @@ -21,6 +21,7 @@ enum SMP_SAVE_MODE_WAV = 2 }; +bool setupExecutablePath(void); int32_t getFileSize(UNICHAR *fileNameU); uint8_t getDiskOpItem(void); void updateCurrSongFilename(void); // for window title @@ -41,6 +42,7 @@ int32_t getExtOffset(char *s, int32_t stringLen); // get byte offset of file ext bool testDiskOpMouseDown(bool mouseHeldDown); void testDiskOpMouseRelease(void); void diskOp_StartDirReadThread(void); +void diskOp_DrawFilelist(void); void diskOp_DrawDirectory(void); void showDiskOpScreen(void); void hideDiskOpScreen(void); diff --git a/src/ft2_events.c b/src/ft2_events.c @@ -35,13 +35,14 @@ #define CRASH_TEXT "Oh no!\nThe Fasttracker II clone has crashed...\n\nA backup .xm was hopefully " \ "saved to the current module directory.\n\nPlease report this bug if you can.\n" \ - "Try to mention what you did before the crash happened." + "Try to mention what you did before the crash happened.\n" \ + "My email can be found at the bottom of 16-bits.org." static bool backupMadeAfterCrash; #ifdef _WIN32 -#define SYSMSG_FILE_ARG (WM_USER + 1) -#define ARGV_SHARED_MEM_MAX_LEN ((MAX_PATH * 2) + 2) +#define SYSMSG_FILE_ARG (WM_USER+1) +#define ARGV_SHARED_MEM_MAX_LEN ((PATH_MAX+1) * sizeof (WCHAR)) #define SHARED_HWND_NAME TEXT("Local\\FT2CloneHwnd") #define SHARED_FILENAME TEXT("Local\\FT2CloneFilename") static HWND hWnd; diff --git a/src/ft2_gui.c b/src/ft2_gui.c @@ -127,20 +127,21 @@ void unstuckLastUsedGUIElement(void) bool setupGUI(void) { - int32_t i; - // all memory will be NULL-tested and free'd if we return false somewhere in this function - editor.tmpFilenameU = (UNICHAR *)calloc(PATH_MAX + 1, sizeof (UNICHAR)); - editor.tmpInstrFilenameU = (UNICHAR *)calloc(PATH_MAX + 1, sizeof (UNICHAR)); + editor.tmpFilenameU = (UNICHAR *)malloc((PATH_MAX + 1) * sizeof (UNICHAR)); + editor.tmpInstrFilenameU = (UNICHAR *)malloc((PATH_MAX + 1) * sizeof (UNICHAR)); if (editor.tmpFilenameU == NULL || editor.tmpInstrFilenameU == NULL) goto setupGUI_OOM; + editor.tmpFilenameU[0] = 0; + editor.tmpInstrFilenameU[0] = 0; + // set uninitialized GUI struct entries textBox_t *t = &textBoxes[1]; // skip first entry, it's reserved for inputBox()) - for (i = 1; i < NUM_TEXTBOXES; i++, t++) + for (int32_t i = 1; i < NUM_TEXTBOXES; i++, t++) { t->visible = false; t->bufOffset = 0; @@ -156,7 +157,7 @@ bool setupGUI(void) } pushButton_t *p = pushButtons; - for (i = 0; i < NUM_PUSHBUTTONS; i++, p++) + for (int32_t i = 0; i < NUM_PUSHBUTTONS; i++, p++) { p->state = 0; p->visible = false; @@ -174,7 +175,7 @@ bool setupGUI(void) } checkBox_t *c = checkBoxes; - for (i = 0; i < NUM_CHECKBOXES; i++, c++) + for (int32_t i = 0; i < NUM_CHECKBOXES; i++, c++) { c->state = 0; c->checked = false; @@ -182,14 +183,14 @@ bool setupGUI(void) } radioButton_t *r = radioButtons; - for (i = 0; i < NUM_RADIOBUTTONS; i++, r++) + for (int32_t i = 0; i < NUM_RADIOBUTTONS; i++, r++) { r->state = 0; r->visible = false; } scrollBar_t *s = scrollBars; - for (i = 0; i < NUM_SCROLLBARS; i++, s++) + for (int32_t i = 0; i < NUM_SCROLLBARS; i++, s++) { s->visible = false; s->state = 0; diff --git a/src/ft2_keyboard.c b/src/ft2_keyboard.c @@ -122,7 +122,8 @@ void keyDownHandler(SDL_Scancode scancode, SDL_Keycode keycode, bool keyWasRepea return; // do NOT repeat keys in Nibbles or if keyRepeat is disabled } - keyb.keyRepeat = true; + if (scancode != SDL_SCANCODE_ESCAPE) + keyb.keyRepeat = true; // handle certain keys (home/end/left/right etc) when editing text if (editor.editTextFlag) @@ -669,6 +670,7 @@ static bool checkModifiedKeys(SDL_Keycode keycode) case SDLK_KP_ENTER: case SDLK_RETURN: + { if (keyb.leftAltPressed) { toggleFullScreen(); @@ -679,9 +681,11 @@ static bool checkModifiedKeys(SDL_Keycode keycode) #endif return true; } - break; + } + break; case SDLK_F9: + { if (keyb.leftCtrlPressed) { startPlaying(PLAYMODE_PATT, editor.ptnJumpPos[0]); @@ -692,9 +696,11 @@ static bool checkModifiedKeys(SDL_Keycode keycode) editor.ptnJumpPos[0] = (uint8_t)editor.pattPos; return true; } - break; + } + break; case SDLK_F10: + { if (keyb.leftCtrlPressed) { startPlaying(PLAYMODE_PATT, editor.ptnJumpPos[1]); @@ -705,9 +711,11 @@ static bool checkModifiedKeys(SDL_Keycode keycode) editor.ptnJumpPos[1] = (uint8_t)editor.pattPos; return true; } - break; + } + break; case SDLK_F11: + { if (keyb.leftCtrlPressed) { startPlaying(PLAYMODE_PATT, editor.ptnJumpPos[2]); @@ -718,9 +726,11 @@ static bool checkModifiedKeys(SDL_Keycode keycode) editor.ptnJumpPos[2] = (uint8_t)editor.pattPos; return true; } - break; + } + break; case SDLK_F12: + { if (keyb.leftCtrlPressed) { startPlaying(PLAYMODE_PATT, editor.ptnJumpPos[3]); @@ -731,9 +741,11 @@ static bool checkModifiedKeys(SDL_Keycode keycode) editor.ptnJumpPos[3] = (uint8_t)editor.pattPos; return true; } - break; + } + break; case SDLK_a: + { if (keyb.leftCtrlPressed) { if (ui.sampleEditorShown) @@ -752,9 +764,11 @@ static bool checkModifiedKeys(SDL_Keycode keycode) return true; } - break; + } + break; case SDLK_b: + { if (keyb.leftCtrlPressed) { if (!ui.aboutScreenShown) @@ -762,9 +776,11 @@ static bool checkModifiedKeys(SDL_Keycode keycode) return true; } - break; + } + break; case SDLK_c: + { if (keyb.leftAltPressed) { if (ui.sampleEditorShown) @@ -793,9 +809,11 @@ static bool checkModifiedKeys(SDL_Keycode keycode) return true; } - break; + } + break; case SDLK_d: + { if (keyb.leftAltPressed) { jumpToChannel(10); @@ -808,9 +826,11 @@ static bool checkModifiedKeys(SDL_Keycode keycode) return true; } - break; + } + break; case SDLK_e: + { if (keyb.leftAltPressed) { jumpToChannel(2); @@ -826,9 +846,11 @@ static bool checkModifiedKeys(SDL_Keycode keycode) showSampleEditorExt(); return true; } - break; + } + break; case SDLK_f: + { #ifdef __APPLE__ if (keyb.leftCommandPressed && keyb.leftCtrlPressed) { @@ -854,17 +876,21 @@ static bool checkModifiedKeys(SDL_Keycode keycode) jumpToChannel(11); return true; } - break; + } + break; case SDLK_g: + { if (keyb.leftAltPressed) { jumpToChannel(12); return true; } - break; + } + break; case SDLK_h: + { if (keyb.leftAltPressed) { jumpToChannel(13); @@ -875,9 +901,11 @@ static bool checkModifiedKeys(SDL_Keycode keycode) showHelpScreen(); return true; } - break; + } + break; case SDLK_i: + { if (keyb.leftAltPressed) { jumpToChannel(7); @@ -888,25 +916,31 @@ static bool checkModifiedKeys(SDL_Keycode keycode) showInstEditor(); return true; } - break; + } + break; case SDLK_j: + { if (keyb.leftAltPressed) { jumpToChannel(14); return true; } - break; + } + break; case SDLK_k: + { if (keyb.leftAltPressed) { jumpToChannel(15); return true; } - break; + } + break; case SDLK_m: + { if (keyb.leftCtrlPressed) { if (ui.aboutScreenShown) hideAboutScreen(); @@ -918,17 +952,21 @@ static bool checkModifiedKeys(SDL_Keycode keycode) return true; } - break; + } + break; case SDLK_n: + { if (keyb.leftCtrlPressed) { showNibblesScreen(); return true; } - break; + } + break; case SDLK_p: + { if (keyb.leftCtrlPressed) { if (!ui.patternEditorShown) @@ -942,17 +980,21 @@ static bool checkModifiedKeys(SDL_Keycode keycode) return true; } - break; + } + break; case SDLK_q: + { if (keyb.leftAltPressed) { jumpToChannel(0); return true; } - break; + } + break; case SDLK_r: + { if (keyb.leftAltPressed) { if (ui.sampleEditorShown) @@ -967,9 +1009,11 @@ static bool checkModifiedKeys(SDL_Keycode keycode) showTrimScreen(); return true; } - break; + } + break; case SDLK_s: + { if (keyb.leftAltPressed) { if (ui.sampleEditorShown) @@ -984,9 +1028,11 @@ static bool checkModifiedKeys(SDL_Keycode keycode) showSampleEditor(); return true; } - break; + } + break; case SDLK_t: + { if (keyb.leftAltPressed) { jumpToChannel(4); @@ -997,17 +1043,21 @@ static bool checkModifiedKeys(SDL_Keycode keycode) showTranspose(); return true; } - break; + } + break; case SDLK_u: + { if (keyb.leftAltPressed) { jumpToChannel(6); return true; } - break; + } + break; case SDLK_v: + { if (keyb.leftAltPressed) { if (ui.sampleEditorShown) @@ -1036,17 +1086,21 @@ static bool checkModifiedKeys(SDL_Keycode keycode) return true; } - break; + } + break; case SDLK_w: + { if (keyb.leftAltPressed) { jumpToChannel(1); return true; } - break; + } + break; case SDLK_x: + { if (keyb.leftAltPressed) { if (ui.sampleEditorShown) @@ -1080,17 +1134,21 @@ static bool checkModifiedKeys(SDL_Keycode keycode) return true; } - break; + } + break; case SDLK_y: + { if (keyb.leftAltPressed) { jumpToChannel(5); return true; } - break; + } + break; case SDLK_z: + { if (keyb.leftAltPressed) { if (ui.sampleEditorShown) @@ -1103,9 +1161,11 @@ static bool checkModifiedKeys(SDL_Keycode keycode) togglePatternEditorExtended(); return true; } - break; + } + break; case SDLK_1: + { if (keyb.leftAltPressed) { if (keyb.leftShiftPressed) @@ -1123,9 +1183,11 @@ static bool checkModifiedKeys(SDL_Keycode keycode) return true; } - break; + } + break; case SDLK_2: + { if (keyb.leftAltPressed) { if (keyb.leftShiftPressed) @@ -1143,9 +1205,11 @@ static bool checkModifiedKeys(SDL_Keycode keycode) return true; } - break; + } + break; case SDLK_3: + { if (keyb.leftAltPressed) { if (keyb.leftShiftPressed) @@ -1163,9 +1227,11 @@ static bool checkModifiedKeys(SDL_Keycode keycode) return true; } - break; + } + break; case SDLK_4: + { if (keyb.leftAltPressed) { if (keyb.leftShiftPressed) @@ -1185,9 +1251,11 @@ static bool checkModifiedKeys(SDL_Keycode keycode) return true; } #endif - break; + } + break; case SDLK_5: + { if (keyb.leftAltPressed) { if (keyb.leftShiftPressed) @@ -1197,9 +1265,11 @@ static bool checkModifiedKeys(SDL_Keycode keycode) return true; } - break; + } + break; case SDLK_6: + { if (keyb.leftAltPressed) { if (keyb.leftShiftPressed) @@ -1209,9 +1279,11 @@ static bool checkModifiedKeys(SDL_Keycode keycode) return true; } - break; + } + break; case SDLK_7: + { if (keyb.leftAltPressed) { if (keyb.leftShiftPressed) @@ -1221,9 +1293,11 @@ static bool checkModifiedKeys(SDL_Keycode keycode) return true; } - break; + } + break; case SDLK_8: + { if (keyb.leftAltPressed) { if (keyb.leftShiftPressed) @@ -1233,9 +1307,11 @@ static bool checkModifiedKeys(SDL_Keycode keycode) return true; } - break; + } + break; case SDLK_9: + { if (keyb.leftAltPressed) { if (keyb.leftShiftPressed) @@ -1245,9 +1321,11 @@ static bool checkModifiedKeys(SDL_Keycode keycode) return true; } - break; + } + break; case SDLK_0: + { if (keyb.leftAltPressed) { if (keyb.leftShiftPressed) @@ -1257,9 +1335,11 @@ static bool checkModifiedKeys(SDL_Keycode keycode) return true; } - break; + } + break; case SDLK_LEFT: + { if (keyb.leftShiftPressed) { decSongPos(); @@ -1275,9 +1355,11 @@ static bool checkModifiedKeys(SDL_Keycode keycode) keybPattMarkLeft(); return true; } - break; + } + break; case SDLK_RIGHT: + { if (keyb.leftShiftPressed) { incSongPos(); @@ -1293,7 +1375,8 @@ static bool checkModifiedKeys(SDL_Keycode keycode) keybPattMarkRight(); return true; } - break; + } + break; } return false; diff --git a/src/ft2_main.c b/src/ft2_main.c @@ -147,9 +147,7 @@ int main(int argc, char *argv[]) #ifdef __APPLE__ osxSetDirToProgramDirFromArgs(argv); #endif - UNICHAR_GETCWD(editor.binaryPathU, PATH_MAX); - - if (!loadBMPs()) + if (!setupExecutablePath() || !loadBMPs()) { cleanUpAndExit(); return 1; @@ -351,22 +349,28 @@ static void cleanUpAndExit(void) // never call this inside the main loop! } #endif - if (editor.audioDevConfigFileLocation != NULL) + if (editor.audioDevConfigFileLocationU != NULL) + { + free(editor.audioDevConfigFileLocationU); + editor.audioDevConfigFileLocationU = NULL; + } + + if (editor.configFileLocationU != NULL) { - free(editor.audioDevConfigFileLocation); - editor.audioDevConfigFileLocation = NULL; + free(editor.configFileLocationU); + editor.configFileLocationU = NULL; } - if (editor.configFileLocation != NULL) + if (editor.midiConfigFileLocationU != NULL) { - free(editor.configFileLocation); - editor.configFileLocation = NULL; + free(editor.midiConfigFileLocationU); + editor.midiConfigFileLocationU = NULL; } - if (editor.midiConfigFileLocation != NULL) + if (editor.binaryPathU != NULL) { - free(editor.midiConfigFileLocation); - editor.midiConfigFileLocation = NULL; + free(editor.binaryPathU); + editor.binaryPathU = NULL; } #ifdef _WIN32 diff --git a/src/ft2_midi.c b/src/ft2_midi.c @@ -18,6 +18,8 @@ #include "ft2_structs.h" #include "rtmidi/rtmidi_c.h" +#define MAX_DEV_STR_LEN 256 + // hide POSIX warnings #ifdef _MSC_VER #pragma warning(disable: 4996) @@ -265,7 +267,7 @@ bool saveMidiInputDeviceToConfig(void) if (midiInStr == NULL) return false; - FILE *f = UNICHAR_FOPEN(editor.midiConfigFileLocation, "w"); + FILE *f = UNICHAR_FOPEN(editor.midiConfigFileLocationU, "w"); if (f == NULL) { free(midiInStr); @@ -281,8 +283,6 @@ bool saveMidiInputDeviceToConfig(void) bool setMidiInputDeviceFromConfig(void) { -#define MAX_DEV_STR_LEN 1024 - uint32_t i; if (midi.inputDeviceName != NULL) @@ -292,17 +292,19 @@ bool setMidiInputDeviceFromConfig(void) if (numDevices == 0) goto setDefMidiInputDev; - FILE *f = UNICHAR_FOPEN(editor.midiConfigFileLocation, "r"); + FILE *f = UNICHAR_FOPEN(editor.midiConfigFileLocationU, "r"); if (f == NULL) goto setDefMidiInputDev; - char *devString = (char *)calloc(MAX_DEV_STR_LEN+4, sizeof (char)); + char *devString = (char *)malloc((MAX_DEV_STR_LEN+4) * sizeof (char)); if (devString == NULL) { fclose(f); goto setDefMidiInputDev; } + devString[0] = '\0'; + if (fgets(devString, MAX_DEV_STR_LEN, f) == NULL) { fclose(f); diff --git a/src/ft2_module_loader.c b/src/ft2_module_loader.c @@ -526,9 +526,7 @@ static void setupLoadedModule(void) bool handleModuleLoadFromArg(int argc, char **argv) { - UNICHAR tmpPathU[PATH_MAX+2]; - - // this is crude, we always expect only one parameter, and that it is the module. + // we always expect only one parameter, and that it is the module if (argc != 2 || argv[1] == NULL || argv[1][0] == '\0') return false; @@ -540,15 +538,26 @@ bool handleModuleLoadFromArg(int argc, char **argv) const uint32_t filenameLen = (const uint32_t)strlen(argv[1]); - UNICHAR *filenameU = (UNICHAR *)calloc(filenameLen+1, sizeof (UNICHAR)); + UNICHAR *tmpPathU = (UNICHAR *)malloc((PATH_MAX + 1) * sizeof (UNICHAR)); + if (tmpPathU == NULL) + { + okBox(0, "System message", "Not enough memory!"); + return false; + } + + UNICHAR *filenameU = (UNICHAR *)malloc((filenameLen + 1) * sizeof (UNICHAR)); if (filenameU == NULL) { + free(tmpPathU); okBox(0, "System message", "Not enough memory!"); return false; } + tmpPathU[0] = 0; + filenameU[0] = 0; + #ifdef _WIN32 - MultiByteToWideChar(CP_UTF8, 0, argv[1], -1, filenameU, filenameLen); + MultiByteToWideChar(CP_UTF8, 0, argv[1], -1, filenameU, filenameLen+1); #else strcpy(filenameU, argv[1]); #endif @@ -562,9 +571,11 @@ bool handleModuleLoadFromArg(int argc, char **argv) const int32_t filesize = getFileSize(filenameU); if (filesize == -1 || filesize >= 512L*1024*1024) // 1) >=2GB 2) >=512MB { - okBox(0, "System message", "Error: The module is too big to be loaded!"); free(filenameU); UNICHAR_CHDIR(tmpPathU); // set old path back + free(tmpPathU); + + okBox(0, "System message", "Error: The module is too big to be loaded!"); return false; } @@ -572,6 +583,8 @@ bool handleModuleLoadFromArg(int argc, char **argv) free(filenameU); UNICHAR_CHDIR(tmpPathU); // set old path back + free(tmpPathU); + return result; } @@ -642,15 +655,17 @@ void loadDroppedFile(char *fullPathUTF8, bool songModifiedCheck) if (fullPathLen == 0) return; - UNICHAR *fullPathU = (UNICHAR *)calloc(fullPathLen + 2, sizeof (UNICHAR)); + UNICHAR *fullPathU = (UNICHAR *)malloc((fullPathLen + 1) * sizeof (UNICHAR)); if (fullPathU == NULL) { okBox(0, "System message", "Not enough memory!"); return; } + fullPathU[0] = 0; + #ifdef _WIN32 - MultiByteToWideChar(CP_UTF8, 0, fullPathUTF8, -1, fullPathU, fullPathLen); + MultiByteToWideChar(CP_UTF8, 0, fullPathUTF8, -1, fullPathU, fullPathLen+1); #else strcpy(fullPathU, fullPathUTF8); #endif diff --git a/src/ft2_mouse.c b/src/ft2_mouse.c @@ -301,7 +301,7 @@ static void changeCursorIfOverTextBoxes(void) textBox_t *t = textBoxes; for (i = 0; i < NUM_TEXTBOXES; i++, t++) { - if (ui.sysReqShown && i > 0) + if (ui.sysReqShown && i != 0) // Sys. Req can only have one (special) text box continue; if (!t->visible) @@ -313,7 +313,10 @@ static void changeCursorIfOverTextBoxes(void) if (my >= t->y && my < t->y+t->h && mx >= t->x && mx < t->x+t->w) { mouse.mouseOverTextBox = true; - setTextEditMouse(); + + if (mouseShape != MOUSE_IDLE_TEXT_EDIT) + setTextEditMouse(); + return; } } diff --git a/src/ft2_structs.h b/src/ft2_structs.h @@ -11,9 +11,8 @@ typedef struct cpu_t typedef struct editor_t { - UNICHAR binaryPathU[PATH_MAX + 2]; - UNICHAR *tmpFilenameU, *tmpInstrFilenameU; // used by saving/loading threads - UNICHAR *configFileLocation, *audioDevConfigFileLocation, *midiConfigFileLocation; + UNICHAR *binaryPathU, *tmpFilenameU, *tmpInstrFilenameU; // used by saving/loading threads + UNICHAR *configFileLocationU, *audioDevConfigFileLocationU, *midiConfigFileLocationU; volatile bool mainLoopOngoing; volatile bool busy, scopeThreadMutex, programRunning, wavIsRendering, wavReachedEndFlag; diff --git a/src/ft2_sysreqs.c b/src/ft2_sysreqs.c @@ -299,8 +299,11 @@ int16_t okBox(int16_t typ, const char *headline, const char *text) { if (inputEvent.key.keysym.sym == SDLK_ESCAPE) { - returnVal = 0; - ui.sysReqShown = false; + if (!inputEvent.key.repeat) // don't let previously held-down ESC immediately close the box + { + returnVal = 0; + ui.sysReqShown = false; + } } else if (inputEvent.key.keysym.sym == SDLK_RETURN) { diff --git a/src/ft2_textboxes.c b/src/ft2_textboxes.c @@ -52,7 +52,7 @@ textBox_t textBoxes[NUM_TEXTBOXES] = // ------ DISK OP. TEXTBOXES ------ // x, y, w, h, tx,ty, maxc, rmb, cmc - { 31, 158, 134, 12, 2, 1, PATH_MAX-1, false, true }, + { 31, 158, 134, 12, 2, 1, PATH_MAX, false, true }, // ------ CONFIG TEXTBOXES ------ // x, y, w, h, tx,ty, maxc, rmb, cmc diff --git a/src/ft2_unicode.c b/src/ft2_unicode.c @@ -57,15 +57,14 @@ char *cp437ToUtf8(char *src) return NULL; } - char *x = (char *)malloc((reqSize + 2) * sizeof (char)); + char *x = (char *)malloc((reqSize + 1) * sizeof (char)); if (x == NULL) { free(w); return NULL; } - x[reqSize+0] = '\0'; - x[reqSize+1] = '\0'; + x[reqSize] = '\0'; retVal = WideCharToMultiByte(CP_UTF8, 0, w, srcLen, x, reqSize, 0, 0); free(w); @@ -148,7 +147,7 @@ char *utf8ToCp437(char *src, bool removeIllegalChars) return NULL; } - char *x = (char *)calloc(reqSize + 1, sizeof (char)); + char *x = (char *)malloc((reqSize + 1) * sizeof (char)); if (x == NULL) { free(w); @@ -216,7 +215,7 @@ char *unicharToCp437(UNICHAR *src, bool removeIllegalChars) { const int8_t ch = (const int8_t)x[i]; if (ch < 32 && ch != 0 && ch != -124 && ch != -108 && - ch != -122 && ch != -114 && ch != -103 && ch != -113) + ch != -122 && ch != -114 && ch != -103 && ch != -113) { x[i] = ' '; // character not allowed, turn it into space } @@ -244,7 +243,7 @@ char *cp437ToUtf8(char *src) size_t outLen = srcLen * 2; // should be sufficient - char *outBuf = (char *)calloc(outLen + 2, sizeof (char)); + char *outBuf = (char *)malloc((outLen + 1) * sizeof (char)); if (outBuf == NULL) return NULL; @@ -266,6 +265,8 @@ char *cp437ToUtf8(char *src) return NULL; } + outBuf[outLen] = '\0'; + return outBuf; } @@ -290,7 +291,7 @@ char *utf8ToCp437(char *src, bool removeIllegalChars) size_t outLen = srcLen * 2; // should be sufficient - char *outBuf = (char *)calloc(outLen + 1, sizeof (char)); + char *outBuf = (char *)malloc((outLen + 1) * sizeof (char)); if (outBuf == NULL) return NULL; @@ -312,6 +313,8 @@ char *utf8ToCp437(char *src, bool removeIllegalChars) return NULL; } + outBuf[outLen] = '\0'; + if (removeIllegalChars) { // remove illegal characters (only allow certain nordic ones) @@ -319,7 +322,7 @@ char *utf8ToCp437(char *src, bool removeIllegalChars) { const int8_t ch = (const int8_t)outBuf[i]; if (ch < 32 && ch != 0 && ch != -124 && ch != -108 && - ch != -122 && ch != -114 && ch != -103 && ch != -113) + ch != -122 && ch != -114 && ch != -103 && ch != -113) { outBuf[i] = ' '; // character not allowed, turn it into space } diff --git a/src/ft2_video.c b/src/ft2_video.c @@ -46,7 +46,7 @@ static const uint8_t textCursorData[12] = video_t video; // globalized static bool songIsModified; -static char wndTitle[128 + PATH_MAX]; +static char wndTitle[256]; static uint64_t timeNext64, timeNext64Frac; static sprite_t sprites[SPRITE_NUM]; @@ -845,10 +845,14 @@ void updateWindowTitle(bool forceUpdate) char *songTitle = getCurrSongFilename(); if (songTitle != NULL) { + char songTitleTrunc[128]; + strncpy(songTitleTrunc, songTitle, sizeof (songTitleTrunc)-1); + songTitleTrunc[sizeof (songTitleTrunc)-1] = '\0'; + if (song.isModified) - sprintf(wndTitle, "Fasttracker II clone v%s - \"%s\" (unsaved)", PROG_VER_STR, songTitle); + sprintf(wndTitle, "Fasttracker II clone v%s - \"%s\" (unsaved)", PROG_VER_STR, songTitleTrunc); else - sprintf(wndTitle, "Fasttracker II clone v%s - \"%s\"", PROG_VER_STR, songTitle); + sprintf(wndTitle, "Fasttracker II clone v%s - \"%s\"", PROG_VER_STR, songTitleTrunc); } else { diff --git a/src/helpdata/FT2.HLP b/src/helpdata/FT2.HLP @@ -923,10 +923,6 @@ END and you need to press a key or click the mouse to abort the render when you want it to. >@X010 ->@C001Mouse / keyboard: -> ->@C002- Linux: The mouse cursor graphics can be glitchy at times... ->@X010 >@C001Video: >@C002 >@X010- Fullscreen mode can be unbearably slow on a Raspberry Pi (even on RPi 4) diff --git a/src/helpdata/ft2_help_data.h b/src/helpdata/ft2_help_data.h @@ -3,9 +3,9 @@ #include <stdint.h> -#define HELP_DATA_LEN 27486 +#define HELP_DATA_LEN 27385 -const uint8_t helpData[27486] = +const uint8_t helpData[27385] = { 0x4C,0x3B,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A, 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A, @@ -2258,46 +2258,38 @@ const uint8_t helpData[27486] = 0x74,0x6F,0x20,0x61,0x62,0x6F,0x72,0x74,0x20,0x74,0x68,0x65, 0x20,0x72,0x65,0x6E,0x64,0x65,0x72,0x20,0x77,0x68,0x65,0x6E, 0x20,0x79,0x6F,0x75,0x20,0x77,0x61,0x6E,0x74,0x06,0x69,0x74, - 0x20,0x74,0x6F,0x2E,0x06,0x3E,0x40,0x58,0x30,0x31,0x30,0x17, - 0x3E,0x40,0x43,0x30,0x30,0x31,0x4D,0x6F,0x75,0x73,0x65,0x20, - 0x2F,0x20,0x6B,0x65,0x79,0x62,0x6F,0x61,0x72,0x64,0x3A,0x01, - 0x3E,0x43,0x3E,0x40,0x43,0x30,0x30,0x32,0x2D,0x20,0x4C,0x69, - 0x6E,0x75,0x78,0x3A,0x20,0x54,0x68,0x65,0x20,0x6D,0x6F,0x75, - 0x73,0x65,0x20,0x63,0x75,0x72,0x73,0x6F,0x72,0x20,0x67,0x72, - 0x61,0x70,0x68,0x69,0x63,0x73,0x20,0x63,0x61,0x6E,0x20,0x62, - 0x65,0x20,0x67,0x6C,0x69,0x74,0x63,0x68,0x79,0x20,0x61,0x74, - 0x20,0x74,0x69,0x6D,0x65,0x73,0x2E,0x2E,0x2E,0x06,0x3E,0x40, - 0x58,0x30,0x31,0x30,0x0C,0x3E,0x40,0x43,0x30,0x30,0x31,0x56, - 0x69,0x64,0x65,0x6F,0x3A,0x06,0x3E,0x40,0x43,0x30,0x30,0x32, - 0x50,0x3E,0x40,0x58,0x30,0x31,0x30,0x2D,0x20,0x46,0x75,0x6C, - 0x6C,0x73,0x63,0x72,0x65,0x65,0x6E,0x20,0x6D,0x6F,0x64,0x65, - 0x20,0x63,0x61,0x6E,0x20,0x62,0x65,0x20,0x75,0x6E,0x62,0x65, - 0x61,0x72,0x61,0x62,0x6C,0x79,0x20,0x73,0x6C,0x6F,0x77,0x20, - 0x6F,0x6E,0x20,0x61,0x20,0x52,0x61,0x73,0x70,0x62,0x65,0x72, - 0x72,0x79,0x20,0x50,0x69,0x20,0x28,0x65,0x76,0x65,0x6E,0x20, - 0x6F,0x6E,0x20,0x52,0x50,0x69,0x20,0x34,0x29,0x01,0x3E,0x52, - 0x3E,0x40,0x58,0x30,0x31,0x30,0x2D,0x20,0x4E,0x6F,0x74,0x20, - 0x61,0x20,0x62,0x75,0x67,0x2C,0x20,0x62,0x75,0x74,0x20,0x69, - 0x66,0x20,0x79,0x6F,0x75,0x72,0x20,0x6D,0x6F,0x6E,0x69,0x74, - 0x6F,0x72,0x27,0x73,0x20,0x72,0x65,0x66,0x72,0x65,0x73,0x68, - 0x20,0x72,0x61,0x74,0x65,0x20,0x69,0x73,0x20,0x6E,0x6F,0x74, - 0x20,0x73,0x65,0x74,0x20,0x74,0x6F,0x20,0x36,0x30,0x48,0x7A, - 0x20,0x28,0x6F,0x72,0x20,0x35,0x39,0x48,0x7A,0x29,0x4F,0x3E, - 0x40,0x58,0x30,0x32,0x31,0x79,0x6F,0x75,0x20,0x6D,0x61,0x79, - 0x20,0x65,0x78,0x70,0x65,0x72,0x69,0x65,0x6E,0x63,0x65,0x20, - 0x76,0x69,0x73,0x75,0x61,0x6C,0x20,0x73,0x74,0x75,0x74,0x74, - 0x65,0x72,0x69,0x6E,0x67,0x20,0x62,0x65,0x63,0x61,0x75,0x73, - 0x65,0x20,0x56,0x53,0x79,0x6E,0x63,0x20,0x77,0x69,0x6C,0x6C, - 0x20,0x6E,0x6F,0x74,0x20,0x62,0x65,0x20,0x75,0x73,0x65,0x64, - 0x20,0x74,0x68,0x65,0x6E,0x2E,0x51,0x49,0x20,0x68,0x69,0x67, - 0x68,0x6C,0x79,0x20,0x72,0x65,0x63,0x6F,0x6D,0x6D,0x65,0x6E, - 0x64,0x20,0x72,0x75,0x6E,0x6E,0x69,0x6E,0x67,0x20,0x79,0x6F, - 0x75,0x72,0x20,0x6D,0x6F,0x6E,0x69,0x74,0x6F,0x72,0x20,0x61, - 0x74,0x20,0x36,0x30,0x48,0x7A,0x20,0x69,0x66,0x20,0x79,0x6F, - 0x75,0x27,0x72,0x65,0x20,0x61,0x20,0x68,0x61,0x72,0x64,0x63, - 0x6F,0x72,0x65,0x20,0x75,0x73,0x65,0x72,0x20,0x6F,0x66,0x20, - 0x74,0x68,0x69,0x73,0x08,0x70,0x72,0x6F,0x67,0x72,0x61,0x6D, - 0x2E,0x00,0x03,0x45,0x4E,0x44 + 0x20,0x74,0x6F,0x2E,0x06,0x3E,0x40,0x58,0x30,0x31,0x30,0x0C, + 0x3E,0x40,0x43,0x30,0x30,0x31,0x56,0x69,0x64,0x65,0x6F,0x3A, + 0x06,0x3E,0x40,0x43,0x30,0x30,0x32,0x50,0x3E,0x40,0x58,0x30, + 0x31,0x30,0x2D,0x20,0x46,0x75,0x6C,0x6C,0x73,0x63,0x72,0x65, + 0x65,0x6E,0x20,0x6D,0x6F,0x64,0x65,0x20,0x63,0x61,0x6E,0x20, + 0x62,0x65,0x20,0x75,0x6E,0x62,0x65,0x61,0x72,0x61,0x62,0x6C, + 0x79,0x20,0x73,0x6C,0x6F,0x77,0x20,0x6F,0x6E,0x20,0x61,0x20, + 0x52,0x61,0x73,0x70,0x62,0x65,0x72,0x72,0x79,0x20,0x50,0x69, + 0x20,0x28,0x65,0x76,0x65,0x6E,0x20,0x6F,0x6E,0x20,0x52,0x50, + 0x69,0x20,0x34,0x29,0x01,0x3E,0x52,0x3E,0x40,0x58,0x30,0x31, + 0x30,0x2D,0x20,0x4E,0x6F,0x74,0x20,0x61,0x20,0x62,0x75,0x67, + 0x2C,0x20,0x62,0x75,0x74,0x20,0x69,0x66,0x20,0x79,0x6F,0x75, + 0x72,0x20,0x6D,0x6F,0x6E,0x69,0x74,0x6F,0x72,0x27,0x73,0x20, + 0x72,0x65,0x66,0x72,0x65,0x73,0x68,0x20,0x72,0x61,0x74,0x65, + 0x20,0x69,0x73,0x20,0x6E,0x6F,0x74,0x20,0x73,0x65,0x74,0x20, + 0x74,0x6F,0x20,0x36,0x30,0x48,0x7A,0x20,0x28,0x6F,0x72,0x20, + 0x35,0x39,0x48,0x7A,0x29,0x4F,0x3E,0x40,0x58,0x30,0x32,0x31, + 0x79,0x6F,0x75,0x20,0x6D,0x61,0x79,0x20,0x65,0x78,0x70,0x65, + 0x72,0x69,0x65,0x6E,0x63,0x65,0x20,0x76,0x69,0x73,0x75,0x61, + 0x6C,0x20,0x73,0x74,0x75,0x74,0x74,0x65,0x72,0x69,0x6E,0x67, + 0x20,0x62,0x65,0x63,0x61,0x75,0x73,0x65,0x20,0x56,0x53,0x79, + 0x6E,0x63,0x20,0x77,0x69,0x6C,0x6C,0x20,0x6E,0x6F,0x74,0x20, + 0x62,0x65,0x20,0x75,0x73,0x65,0x64,0x20,0x74,0x68,0x65,0x6E, + 0x2E,0x51,0x49,0x20,0x68,0x69,0x67,0x68,0x6C,0x79,0x20,0x72, + 0x65,0x63,0x6F,0x6D,0x6D,0x65,0x6E,0x64,0x20,0x72,0x75,0x6E, + 0x6E,0x69,0x6E,0x67,0x20,0x79,0x6F,0x75,0x72,0x20,0x6D,0x6F, + 0x6E,0x69,0x74,0x6F,0x72,0x20,0x61,0x74,0x20,0x36,0x30,0x48, + 0x7A,0x20,0x69,0x66,0x20,0x79,0x6F,0x75,0x27,0x72,0x65,0x20, + 0x61,0x20,0x68,0x61,0x72,0x64,0x63,0x6F,0x72,0x65,0x20,0x75, + 0x73,0x65,0x72,0x20,0x6F,0x66,0x20,0x74,0x68,0x69,0x73,0x08, + 0x70,0x72,0x6F,0x67,0x72,0x61,0x6D,0x2E,0x00,0x03,0x45,0x4E, + 0x44 }; #endif