History

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

Olav Sørensen committed 5 years ago

Commit 8af2e421 parent 6a594c819 files · +550 −380Browse files

Unified · Split

19 files
  1. src/ft2_audio.c +7 −19
  2. src/ft2_audioselector.c +104 −84
  3. src/ft2_config.c +70 −67
  4. src/ft2_diskop.c +117 −66
  5. src/ft2_diskop.h +2 −0
  6. src/ft2_events.c +4 −3
  7. src/ft2_gui.c +10 −9
  8. src/ft2_keyboard.c +125 −42
  9. src/ft2_main.c +16 −12
  10. src/ft2_midi.c +7 −5
  11. src/ft2_module_loader.c +23 −8
  12. src/ft2_mouse.c +5 −2
  13. src/ft2_structs.h +2 −3
  14. src/ft2_sysreqs.c +5 −2
  15. src/ft2_textboxes.c +1 −1
  16. src/ft2_unicode.c +11 −8
  17. src/ft2_video.c +7 −3
  18. src/helpdata/FT2.HLP +0 −4
  19. src/helpdata/ft2_help_data.h +34 −42
src/ft2_audio.c+7−19
@@ -20,6 +20,11 @@ · 19 unmodified lines
2020 #include "mixer/ft2_silence_mix.h"
2121 // --------------------------------
2222
23+// hide POSIX warnings
24+#ifdef _MSC_VER
25+#pragma warning(disable: 4996)
26+#endif
27+
2328 #define INITIAL_DITHER_SEED 0x12345000
2429
2530 static int8_t pmpCountDiv, pmpChannels = 2;
@@ -87,14 +92,7 @@ bool setNewAudioSettings(void) // only call this from the main input/video threa · 61 unmodified lines
8792 audio.currOutputDevice = NULL;
8893 }
8994
90− const uint32_t stringLen = (uint32_t)strlen(audio.lastWorkingAudioDeviceName);
91−
92− audio.currOutputDevice = (char *)malloc(stringLen + 2);
93− if (audio.currOutputDevice != NULL)
94− {
95− strcpy(audio.currOutputDevice, audio.lastWorkingAudioDeviceName);
96− audio.currOutputDevice[stringLen + 1] = '\0'; // UTF-8 needs double null termination
97− }
95+ audio.currOutputDevice = strdup(audio.lastWorkingAudioDeviceName);
9896 }
9997
10098 // also update config audio radio buttons if we're on that screen at the moment
@@ -1050,17 +1048,7 @@ static void setLastWorkingAudioDevName(void) · 949 unmodified lines
10501048 }
10511049
10521050 if (audio.currOutputDevice != NULL)
1053− {
1054− const uint32_t stringLen = (uint32_t)strlen(audio.currOutputDevice);
1055−
1056− audio.lastWorkingAudioDeviceName = (char *)malloc(stringLen + 2);
1057− if (audio.lastWorkingAudioDeviceName != NULL)
1058− {
1059− if (stringLen > 0)
1060− strcpy(audio.lastWorkingAudioDeviceName, audio.currOutputDevice);
1061− audio.lastWorkingAudioDeviceName[stringLen + 1] = '\0'; // UTF-8 needs double null termination
1062− }
1063− }
1051+ audio.lastWorkingAudioDeviceName = strdup(audio.currOutputDevice);
10641052 }
10651053
10661054 bool setupAudio(bool showErrorMsg)
src/ft2_audioselector.c+104−84
@@ -13,53 +13,75 @@ · 12 unmodified lines
1313 #include "ft2_audioselector.h"
1414 #include "ft2_structs.h"
1515
16−char *getAudioOutputDeviceFromConfig(void)
16+enum
1717 {
18+ INPUT_DEVICE = 0,
19+ OUTPUT_DEVICE = 1
20+};
21+
1822 #define MAX_DEV_STR_LEN 256
1923
20− char *devString = (char *)calloc(MAX_DEV_STR_LEN + 1, sizeof (char));
21− if (devString == NULL)
24+// hide POSIX warnings
25+#ifdef _MSC_VER
26+#pragma warning(disable: 4996)
27+#endif
28+
29+static char *getReasonableAudioDevice(int32_t iscapture) // can and will return NULL
30+{
31+ int32_t numAudioDevs = SDL_GetNumAudioDevices(iscapture);
32+ if (numAudioDevs == 0 || numAudioDevs > 1)
33+ return NULL; // we don't know which audio output device is the default device
34+
35+ const char *devName = SDL_GetAudioDeviceName(0, iscapture);
36+ if (devName == NULL)
2237 return NULL;
2338
24− FILE *f = UNICHAR_FOPEN(editor.audioDevConfigFileLocation, "r");
25− if (f == NULL)
39+ return strdup(devName);
40+}
41+
42+char *getAudioOutputDeviceFromConfig(void)
43+{
44+ bool audioDeviceRead = false;
45+ char *devString = NULL;
46+
47+ FILE *f = UNICHAR_FOPEN(editor.audioDevConfigFileLocationU, "r");
48+ if (f != NULL)
2649 {
27−#if defined(__APPLE__)
28− 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
29−#else
30− const char *devStringTmp = SDL_GetAudioDeviceName(0, false);
31− if (devStringTmp == NULL)
50+ devString = (char *)malloc(MAX_DEV_STR_LEN+1);
51+ if (devString == NULL)
3252 {
33− free(devString);
34− return NULL;
53+ fclose(f);
54+ return NULL; // out of memory
3555 }
3656
37− const uint32_t devStringLen = (uint32_t)strlen(devStringTmp);
57+ devString[0] = '\0';
58+ fgets(devString, MAX_DEV_STR_LEN, f);
59+ fclose(f);
60+
61+ const int32_t devStringLen = (int32_t)strlen(devString);
3862 if (devStringLen > 0)
39− strncpy(devString, devStringTmp, MAX_DEV_STR_LEN);
40− devString[devStringLen+1] = '\0'; // UTF-8 needs double null termination
41−#endif
42− }
43− else
44− {
45− if (fgets(devString, MAX_DEV_STR_LEN, f) == NULL)
4663 {
47− free(devString);
48− fclose(f);
49− return NULL;
64+ if (devString[devStringLen-1] == '\n')
65+ devString[devStringLen-1] = ' ';
66+
67+ if (!(devStringLen == 1 && devString[0] == ' ')) // space only = no device
68+ audioDeviceRead = true;
5069 }
70+ }
5171
52− const uint32_t devStringLen = (uint32_t)strlen(devString);
53− if (devString[devStringLen-1] == '\n')
54− devString[devStringLen-1] = '\0';
55− devString[devStringLen+1] = '\0'; // UTF-8 needs double null termination
72+ if (!audioDeviceRead)
73+ {
74+ if (devString != NULL)
75+ free(devString);
5676
57−#if defined(__APPLE__)
58− if (devString[0] == '\0')
59− return NULL; // macOS SDL2 locks up indefinitely if fed an empty string for device name
60−#endif
77+ devString = getReasonableAudioDevice(OUTPUT_DEVICE);
78+ }
6179
62− fclose(f);
80+ // SDL_OpenAudioDevice() doesn't seem to like an empty audio device string
81+ if (devString != NULL && devString[0] == '\0')
82+ {
83+ free(devString);
84+ return NULL;
6385 }
6486
6587 return devString;
@@ -67,50 +89,48 @@ char *getAudioOutputDeviceFromConfig(void) · 1 unmodified line
6789
6890 char *getAudioInputDeviceFromConfig(void)
6991 {
70−#define MAX_DEV_STR_LEN 256
92+ bool audioDeviceRead = false;
93+ char *devString = NULL;
7194
72− char *devString = (char *)calloc(MAX_DEV_STR_LEN + 1, sizeof (char));
73− if (devString == NULL)
74− return NULL;
75−
76− FILE *f = UNICHAR_FOPEN(editor.audioDevConfigFileLocation, "r");
77− if (f == NULL)
95+ FILE *f = UNICHAR_FOPEN(editor.audioDevConfigFileLocationU, "r");
96+ if (f != NULL)
7897 {
79− const char *devStringTmp = SDL_GetAudioDeviceName(0, true);
80− if (devStringTmp == NULL)
98+ devString = (char *)malloc(MAX_DEV_STR_LEN+1);
99+ if (devString == NULL)
81100 {
82− free(devString);
83− return NULL;
101+ fclose(f);
102+ return NULL; // out of memory
84103 }
85104
86− const uint32_t devStringLen = (uint32_t)strlen(devStringTmp);
105+ devString[0] = '\0';
106+ fgets(devString, MAX_DEV_STR_LEN, f); // skip first line (we want the input device)
107+ fgets(devString, MAX_DEV_STR_LEN, f);
108+ fclose(f);
109+
110+ const int32_t devStringLen = (int32_t)strlen(devString);
87111 if (devStringLen > 0)
88− strncpy(devString, devStringTmp, MAX_DEV_STR_LEN);
89− devString[devStringLen+1] = '\0'; // UTF-8 needs double null termination
90− }
91− else
92− {
93− if (fgets(devString, MAX_DEV_STR_LEN, f) == NULL)
94112 {
95− free(devString);
96− fclose(f);
97− return NULL;
113+ if (devString[devStringLen-1] == '\n')
114+ devString[devStringLen-1] = ' ';
115+
116+ if (!(devStringLen == 1 && devString[0] == ' ')) // space only = no device
117+ audioDeviceRead = true;
98118 }
119+ }
99120
100− // do it one more time (next line)
101− if (fgets(devString, MAX_DEV_STR_LEN, f) == NULL)
102− {
121+ if (!audioDeviceRead)
122+ {
123+ if (devString != NULL)
103124 free(devString);
104− fclose(f);
105− return NULL;
106− }
107125
108− const uint32_t devStringLen = (uint32_t)strlen(devString);
109− if (devString[devStringLen-1] == '\n')
110− devString[devStringLen-1] = '\0';
111− devString[devStringLen+1] = '\0'; // UTF-8 needs double null termination
126+ devString = getReasonableAudioDevice(INPUT_DEVICE);
127+ }
112128
113− fclose(f);
129+ // SDL_OpenAudioDevice() doesn't seem to like an empty audio device string
130+ if (devString != NULL && devString[0] == '\0')
131+ {
132+ free(devString);
133+ return NULL;
114134 }
115135
116136 return devString;
@@ -118,15 +138,21 @@ char *getAudioInputDeviceFromConfig(void) · 1 unmodified line
118138
119139 bool saveAudioDevicesToConfig(const char *outputDevice, const char *inputDevice)
120140 {
121− FILE *f = UNICHAR_FOPEN(editor.audioDevConfigFileLocation, "w");
141+ FILE *f = UNICHAR_FOPEN(editor.audioDevConfigFileLocationU, "w");
122142 if (f == NULL)
123143 return false;
124144
125145 if (outputDevice != NULL)
126146 fputs(outputDevice, f);
147+ else
148+ fputc(' ', f);
149+
127150 fputc('\n', f);
151+
128152 if (inputDevice != NULL)
129153 fputs(inputDevice, f);
154+ else
155+ fputc(' ', f);
130156
131157 fclose(f);
132158 return true;
@@ -231,13 +257,14 @@ bool testAudioDeviceListsMouseDown(void) · 98 unmodified lines
231257
232258 const uint32_t devStringLen = (uint32_t)strlen(devString);
233259
234− audio.currOutputDevice = (char *)malloc(devStringLen + 2);
260+ audio.currOutputDevice = (char *)malloc(devStringLen+1);
235261 if (audio.currOutputDevice == NULL)
236262 return true;
237263
264+ audio.currOutputDevice[0] = '\0';
265+
238266 if (devStringLen > 0)
239267 strcpy(audio.currOutputDevice, devString);
240− audio.currOutputDevice[devStringLen+1] = '\0'; // UTF-8 needs double null termination
241268
242269 if (!setNewAudioSettings())
243270 okBox(0, "System message", "Couldn't open audio input device!");
@@ -263,13 +290,14 @@ bool testAudioDeviceListsMouseDown(void) · 19 unmodified lines
263290
264291 const uint32_t devStringLen = (uint32_t)strlen(devString);
265292
266− audio.currInputDevice = (char *)malloc(devStringLen + 2);
293+ audio.currInputDevice = (char *)malloc(devStringLen+1);
267294 if (audio.currInputDevice == NULL)
268295 return true;
269296
297+ audio.currInputDevice[0] = '\0';
298+
270299 if (devStringLen > 0)
271300 strcpy(audio.currInputDevice, devString);
272− audio.currInputDevice[devStringLen+1] = '\0'; // UTF-8 needs double null termination
273301
274302 drawAudioInputList();
275303 }
@@ -303,10 +331,10 @@ void freeAudioDeviceLists(void) · 27 unmodified lines
303331
304332 void freeAudioDeviceSelectorBuffers(void)
305333 {
306− if (editor.audioDevConfigFileLocation != NULL)
334+ if (editor.audioDevConfigFileLocationU != NULL)
307335 {
308− free(editor.audioDevConfigFileLocation);
309− editor.audioDevConfigFileLocation = NULL;
336+ free(editor.audioDevConfigFileLocationU);
337+ editor.audioDevConfigFileLocationU = NULL;
310338 }
311339
312340 if (audio.currOutputDevice != NULL)
@@ -352,14 +380,12 @@ void setToDefaultAudioOutputDevice(void) · 39 unmodified lines
352380 audio.currOutputDevice = NULL;
353381 }
354382
355− audio.currOutputDevice = (char *)malloc(stringLen + 2);
383+ audio.currOutputDevice = (char *)malloc(stringLen + 1);
356384 if (audio.currOutputDevice == NULL)
357385 return;
358386
359387 if (stringLen > 0)
360388 strcpy(audio.currOutputDevice, devString);
361−
362− audio.currOutputDevice[stringLen+1] = '\0'; // UTF-8 needs double null termination
363389 }
364390
365391 void setToDefaultAudioInputDevice(void)
@@ -384,14 +410,12 @@ void setToDefaultAudioInputDevice(void) · 18 unmodified lines
384410 audio.currInputDevice = NULL;
385411 }
386412
387− audio.currInputDevice = (char *)malloc(stringLen + 2);
413+ audio.currInputDevice = (char *)malloc(stringLen + 1);
388414 if (audio.currInputDevice == NULL)
389415 return;
390416
391417 if (stringLen > 0)
392418 strcpy(audio.currInputDevice, devString);
393−
394− audio.currInputDevice[stringLen+1] = '\0'; // UTF-8 needs double null termination
395419 }
396420
397421 void rescanAudioDevices(void)
@@ -417,14 +441,12 @@ void rescanAudioDevices(void) · 19 unmodified lines
417441
418442 const uint32_t stringLen = (uint32_t)strlen(deviceName);
419443
420− audio.outputDeviceNames[i] = (char *)malloc(stringLen + 2);
444+ audio.outputDeviceNames[i] = (char *)malloc(stringLen + 1);
421445 if (audio.outputDeviceNames[i] == NULL)
422446 break;
423447
424448 if (stringLen > 0)
425449 strcpy(audio.outputDeviceNames[i], deviceName);
426−
427− audio.outputDeviceNames[i][stringLen+1] = '\0'; // UTF-8 needs double null termination
428450 }
429451
430452 // GET AUDIO INPUT DEVICES
@@ -444,14 +466,12 @@ void rescanAudioDevices(void) · 13 unmodified lines
444466
445467 const uint32_t stringLen = (uint32_t)strlen(deviceName);
446468
447− audio.inputDeviceNames[i] = (char *)malloc(stringLen + 2);
469+ audio.inputDeviceNames[i] = (char *)malloc(stringLen + 1);
448470 if (audio.inputDeviceNames[i] == NULL)
449471 break;
450472
451473 if (stringLen > 0)
452474 strcpy(audio.inputDeviceNames[i], deviceName);
453−
454− audio.inputDeviceNames[i][stringLen+1] = '\0'; // UTF-8 needs double null termination
455475 }
456476
457477 setScrollBarEnd(SB_AUDIO_OUTPUT_SCROLL, audio.outputDeviceNum);
src/ft2_config.c+70−67
@@ -264,7 +264,7 @@ bool loadConfig(bool showErrorFlag) · 263 unmodified lines
264264 }
265265 #endif
266266
267− if (editor.configFileLocation == NULL)
267+ if (editor.configFileLocationU == NULL)
268268 {
269269 if (showErrorFlag)
270270 okBox(0, "System message", "Error opening config file for reading!");
@@ -272,7 +272,7 @@ bool loadConfig(bool showErrorFlag) · 1 unmodified line
272272 return false;
273273 }
274274
275− FILE *f = UNICHAR_FOPEN(editor.configFileLocation, "rb");
275+ FILE *f = UNICHAR_FOPEN(editor.configFileLocationU, "rb");
276276 if (f == NULL)
277277 {
278278 if (showErrorFlag)
@@ -353,7 +353,7 @@ void loadConfig2(void) // called by "Load config" button · 74 unmodified lines
353353
354354 bool saveConfig(bool showErrorFlag)
355355 {
356− if (editor.configFileLocation == NULL)
356+ if (editor.configFileLocationU == NULL)
357357 {
358358 if (showErrorFlag)
359359 okBox(0, "System message", "General I/O error during saving! Is the file in use?");
@@ -366,7 +366,7 @@ bool saveConfig(bool showErrorFlag) · 6 unmodified lines
366366 saveMidiInputDeviceToConfig();
367367 #endif
368368
369− FILE *f = UNICHAR_FOPEN(editor.configFileLocation, "wb");
369+ FILE *f = UNICHAR_FOPEN(editor.configFileLocationU, "wb");
370370 if (f == NULL)
371371 {
372372 if (showErrorFlag)
@@ -410,14 +410,14 @@ void saveConfig2(void) // called by "Save config" button · 37 unmodified lines
410410 saveConfig(CONFIG_SHOW_ERRORS);
411411 }
412412
413−static UNICHAR *getFullAudDevConfigPath(void) // kinda hackish
413+static UNICHAR *getFullAudDevConfigPathU(void) // kinda hackish
414414 {
415415 int32_t audiodevDotIniStrLen, ft2DotCfgStrLen;
416416
417− if (editor.configFileLocation == NULL)
417+ if (editor.configFileLocationU == NULL)
418418 return NULL;
419419
420− const int32_t ft2ConfPathLen = (int32_t)UNICHAR_STRLEN(editor.configFileLocation);
420+ const int32_t ft2ConfPathLen = (int32_t)UNICHAR_STRLEN(editor.configFileLocationU);
421421
422422 #ifdef _WIN32
423423 audiodevDotIniStrLen = (int32_t)UNICHAR_STRLEN(L"audiodev.ini");
@@ -427,31 +427,29 @@ static UNICHAR *getFullAudDevConfigPath(void) // kinda hackish · 3 unmodified lines
427427 ft2DotCfgStrLen = (int32_t)UNICHAR_STRLEN("FT2.CFG");
428428 #endif
429429
430− UNICHAR *filePath = (UNICHAR *)calloc(ft2ConfPathLen + audiodevDotIniStrLen + 2, sizeof (UNICHAR));
430+ UNICHAR *filePathU = (UNICHAR *)malloc((ft2ConfPathLen + audiodevDotIniStrLen + 1) * sizeof (UNICHAR));
431+ filePathU[0] = 0;
431432
432− UNICHAR_STRCPY(filePath, editor.configFileLocation);
433−
434− const int32_t stringOffset = ft2ConfPathLen - ft2DotCfgStrLen;
435− filePath[stringOffset+0] = '\0';
436− filePath[stringOffset+1] = '\0';
433+ UNICHAR_STRCPY(filePathU, editor.configFileLocationU);
434+ filePathU[ft2ConfPathLen-ft2DotCfgStrLen] = 0;
437435
438436 #ifdef _WIN32
439− UNICHAR_STRCAT(filePath, L"audiodev.ini");
437+ UNICHAR_STRCAT(filePathU, L"audiodev.ini");
440438 #else
441− UNICHAR_STRCAT(filePath, "audiodev.ini");
439+ UNICHAR_STRCAT(filePathU, "audiodev.ini");
442440 #endif
443441
444− return filePath;
442+ return filePathU;
445443 }
446444
447−static UNICHAR *getFullMidiDevConfigPath(void) // kinda hackish
445+static UNICHAR *getFullMidiDevConfigPathU(void) // kinda hackish
448446 {
449447 int32_t mididevDotIniStrLen, ft2DotCfgStrLen;
450448
451− if (editor.configFileLocation == NULL)
449+ if (editor.configFileLocationU == NULL)
452450 return NULL;
453451
454− const int32_t ft2ConfPathLen = (int32_t)UNICHAR_STRLEN(editor.configFileLocation);
452+ const int32_t ft2ConfPathLen = (int32_t)UNICHAR_STRLEN(editor.configFileLocationU);
455453
456454 #ifdef _WIN32
457455 mididevDotIniStrLen = (int32_t)UNICHAR_STRLEN(L"mididev.ini");
@@ -461,21 +459,19 @@ static UNICHAR *getFullMidiDevConfigPath(void) // kinda hackish · 3 unmodified lines
461459 ft2DotCfgStrLen = (int32_t)UNICHAR_STRLEN("FT2.CFG");
462460 #endif
463461
464− UNICHAR *filePath = (UNICHAR *)calloc(ft2ConfPathLen + mididevDotIniStrLen + 2, sizeof (UNICHAR));
465−
466− UNICHAR_STRCPY(filePath, editor.configFileLocation);
462+ UNICHAR *filePathU = (UNICHAR *)malloc((ft2ConfPathLen + mididevDotIniStrLen + 1) * sizeof (UNICHAR));
463+ filePathU[0] = 0;
467464
468− const int32_t stringOffset = ft2ConfPathLen - ft2DotCfgStrLen;
469− filePath[stringOffset+0] = '\0';
470− filePath[stringOffset+1] = '\0';
465+ UNICHAR_STRCPY(filePathU, editor.configFileLocationU);
466+ filePathU[ft2ConfPathLen-ft2DotCfgStrLen] = 0;
471467
472468 #ifdef _WIN32
473− UNICHAR_STRCAT(filePath, L"mididev.ini");
469+ UNICHAR_STRCAT(filePathU, L"mididev.ini");
474470 #else
475− UNICHAR_STRCAT(filePath, "mididev.ini");
471+ UNICHAR_STRCAT(filePathU, "mididev.ini");
476472 #endif
477473
478− return filePath;
474+ return filePathU;
479475 }
480476
481477 static void setConfigFileLocation(void) // kinda hackish
@@ -484,41 +480,44 @@ static void setConfigFileLocation(void) // kinda hackish · 2 unmodified lines
484480 #ifdef _WIN32
485481 int32_t ft2DotCfgStrLen = (int32_t)UNICHAR_STRLEN(L"FT2.CFG");
486482
487− UNICHAR *oldPath = (UNICHAR *)calloc(PATH_MAX + 8 + 2, sizeof (UNICHAR));
488− UNICHAR *tmpPath = (UNICHAR *)calloc(PATH_MAX + 8 + 2, sizeof (UNICHAR));
489− editor.configFileLocation = (UNICHAR *)calloc(PATH_MAX + ft2DotCfgStrLen + 2, sizeof (UNICHAR));
483+ UNICHAR *oldPathU = (UNICHAR *)malloc((PATH_MAX + 8 + 1) * sizeof (UNICHAR));
484+ UNICHAR *tmpPathU = (UNICHAR *)malloc((PATH_MAX + 8 + 1) * sizeof (UNICHAR));
485+ editor.configFileLocationU = (UNICHAR *)malloc((PATH_MAX + ft2DotCfgStrLen + 1) * sizeof (UNICHAR));
490486
491− if (oldPath == NULL || tmpPath == NULL || editor.configFileLocation == NULL)
487+ if (oldPathU == NULL || tmpPathU == NULL || editor.configFileLocationU == NULL)
492488 {
493− if (oldPath != NULL) free(oldPath);
494− if (tmpPath != NULL) free(tmpPath);
495− if (editor.configFileLocation != NULL) free(editor.configFileLocation);
489+ if (oldPathU != NULL) free(oldPathU);
490+ if (tmpPathU != NULL) free(tmpPathU);
491+ if (editor.configFileLocationU != NULL) free(editor.configFileLocationU);
496492
497− editor.configFileLocation = NULL;
493+ editor.configFileLocationU = NULL;
498494 showErrorMsgBox("Error: Couldn't set config file location. You can't load/save the config!");
499495 return;
500496 }
501497
502− if (GetCurrentDirectoryW(PATH_MAX - ft2DotCfgStrLen - 1, oldPath) == 0)
498+ oldPathU[0] = 0;
499+ tmpPathU[0] = 0;
500+
501+ if (GetCurrentDirectoryW(PATH_MAX - ft2DotCfgStrLen - 1, oldPathU) == 0)
503502 {
504− free(oldPath);
505− free(tmpPath);
506− free(editor.configFileLocation);
503+ free(oldPathU);
504+ free(tmpPathU);
505+ free(editor.configFileLocationU);
507506
508− editor.configFileLocation = NULL;
507+ editor.configFileLocationU = NULL;
509508 showErrorMsgBox("Error: Couldn't set config file location. You can't load/save the config!");
510509 return;
511510 }
512511
513− UNICHAR_STRCPY(editor.configFileLocation, oldPath);
512+ UNICHAR_STRCPY(editor.configFileLocationU, oldPathU);
514513
515514 FILE *f = fopen("FT2.CFG", "rb");
516515 if (f == NULL) // FT2.CFG not found in current dir, try default config dir
517516 {
518− int32_t result = SHGetFolderPathW(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, tmpPath);
517+ int32_t result = SHGetFolderPathW(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, tmpPathU);
519518 if (result == S_OK)
520519 {
521− if (SetCurrentDirectoryW(tmpPath) != 0)
520+ if (SetCurrentDirectoryW(tmpPathU) != 0)
522521 {
523522 result = chdir("FT2 clone");
524523 if (result != 0)
@@ -528,7 +527,7 @@ static void setConfigFileLocation(void) // kinda hackish · 3 unmodified lines
528527 }
529528
530529 if (result == 0)
531− GetCurrentDirectoryW(PATH_MAX - ft2DotCfgStrLen - 1, editor.configFileLocation); // we can, set it
530+ GetCurrentDirectoryW(PATH_MAX - ft2DotCfgStrLen - 1, editor.configFileLocationU); // we can, set it
532531 }
533532 }
534533 }
@@ -537,27 +536,29 @@ static void setConfigFileLocation(void) // kinda hackish · 2 unmodified lines
537536 fclose(f);
538537 }
539538
540− free(tmpPath);
541− SetCurrentDirectoryW(oldPath);
542− free(oldPath);
539+ free(tmpPathU);
540+ SetCurrentDirectoryW(oldPathU);
541+ free(oldPathU);
543542
544− UNICHAR_STRCAT(editor.configFileLocation, L"\\FT2.CFG");
543+ UNICHAR_STRCAT(editor.configFileLocationU, L"\\FT2.CFG");
545544
546545 // OS X / macOS
547546 #elif defined __APPLE__
548547 int32_t ft2DotCfgStrLen = (int32_t)UNICHAR_STRLEN("FT2.CFG");
549548
550− editor.configFileLocation = (UNICHAR *)calloc(PATH_MAX + ft2DotCfgStrLen + 2, sizeof (UNICHAR));
551− if (editor.configFileLocation == NULL)
549+ editor.configFileLocationU = (UNICHAR *)malloc((PATH_MAX + ft2DotCfgStrLen + 1) * sizeof (UNICHAR));
550+ if (editor.configFileLocationU == NULL)
552551 {
553552 showErrorMsgBox("Error: Couldn't set config file location. You can't load/save the config!");
554553 return;
555554 }
556555
557− if (getcwd(editor.configFileLocation, PATH_MAX - ft2DotCfgStrLen - 1) == NULL)
556+ editor.configFileLocationU[0] = 0;
557+
558+ if (getcwd(editor.configFileLocationU, PATH_MAX - ft2DotCfgStrLen - 1) == NULL)
558559 {
559− free(editor.configFileLocation);
560− editor.configFileLocation = NULL;
560+ free(editor.configFileLocationU);
561+ editor.configFileLocationU = NULL;
561562 showErrorMsgBox("Error: Couldn't set config file location. You can't load/save the config!");
562563 return;
563564 }
@@ -578,7 +579,7 @@ static void setConfigFileLocation(void) // kinda hackish · 14 unmodified lines
578579 }
579580
580581 if (result == 0)
581− getcwd(editor.configFileLocation, PATH_MAX - ft2DotCfgStrLen - 1);
582+ getcwd(editor.configFileLocationU, PATH_MAX - ft2DotCfgStrLen - 1);
582583 }
583584 }
584585 }
@@ -587,23 +588,25 @@ static void setConfigFileLocation(void) // kinda hackish · 2 unmodified lines
587588 fclose(f);
588589 }
589590
590− strcat(editor.configFileLocation, "/FT2.CFG");
591+ strcat(editor.configFileLocationU, "/FT2.CFG");
591592
592593 // Linux etc
593594 #else
594595 int32_t ft2DotCfgStrLen = (int32_t)UNICHAR_STRLEN("FT2.CFG");
595596
596− editor.configFileLocation = (UNICHAR *)calloc(PATH_MAX + ft2DotCfgStrLen + 2, sizeof (UNICHAR));
597− if (editor.configFileLocation == NULL)
597+ editor.configFileLocationU = (UNICHAR *)malloc((PATH_MAX + ft2DotCfgStrLen + 1) * sizeof (UNICHAR));
598+ if (editor.configFileLocationU == NULL)
598599 {
599600 showErrorMsgBox("Error: Couldn't set config file location. You can't load/save the config!");
600601 return;
601602 }
602603
603− if (getcwd(editor.configFileLocation, PATH_MAX - ft2DotCfgStrLen - 1) == NULL)
604+ editor.configFileLocationU[0] = 0;
605+
606+ if (getcwd(editor.configFileLocationU, PATH_MAX - ft2DotCfgStrLen - 1) == NULL)
604607 {
605− free(editor.configFileLocation);
606− editor.configFileLocation = NULL;
608+ free(editor.configFileLocationU);
609+ editor.configFileLocationU = NULL;
607610 showErrorMsgBox("Error: Couldn't set config file location. You can't load/save the config!");
608611 return;
609612 }
@@ -632,7 +635,7 @@ static void setConfigFileLocation(void) // kinda hackish · 22 unmodified lines
632635 }
633636
634637 if (result == 0)
635− getcwd(editor.configFileLocation, PATH_MAX - ft2DotCfgStrLen - 1);
638+ getcwd(editor.configFileLocationU, PATH_MAX - ft2DotCfgStrLen - 1);
636639 }
637640 }
638641 else
@@ -640,23 +643,23 @@ static void setConfigFileLocation(void) // kinda hackish · 1 unmodified line
640643 fclose(f);
641644 }
642645
643− strcat(editor.configFileLocation, "/FT2.CFG");
646+ strcat(editor.configFileLocationU, "/FT2.CFG");
644647 #endif
645648
646− editor.midiConfigFileLocation = getFullMidiDevConfigPath();
647− editor.audioDevConfigFileLocation = getFullAudDevConfigPath();
649+ editor.midiConfigFileLocationU = getFullMidiDevConfigPathU();
650+ editor.audioDevConfigFileLocationU = getFullAudDevConfigPathU();
648651 }
649652
650653 void loadConfigOrSetDefaults(void)
651654 {
652655 setConfigFileLocation();
653− if (editor.configFileLocation == NULL)
656+ if (editor.configFileLocationU == NULL)
654657 {
655658 setDefaultConfigSettings();
656659 return;
657660 }
658661
659− FILE *f = UNICHAR_FOPEN(editor.configFileLocation, "rb");
662+ FILE *f = UNICHAR_FOPEN(editor.configFileLocationU, "rb");
660663 if (f == NULL)
661664 {
662665 setDefaultConfigSettings();
src/ft2_diskop.c+117−66
@@ -72,7 +72,7 @@ typedef struct DirRec · 71 unmodified lines
7272 int32_t filesize;
7373 } DirRec;
7474
75−static char FReq_SysReqText[196], *FReq_FileName, *FReq_NameTemp;
75+static char FReq_SysReqText[256], *FReq_FileName, *FReq_NameTemp;
7676 static char *modTmpFName, *insTmpFName, *smpTmpFName, *patTmpFName, *trkTmpFName;
7777 static char *modTmpFNameUTF8; // for window title
7878 static uint8_t FReq_Item;
@@ -84,6 +84,18 @@ static SDL_Thread *thread; · 5 unmodified lines
8484
8585 static void setDiskOpItem(uint8_t item);
8686
87+bool setupExecutablePath(void)
88+{
89+ editor.binaryPathU = (UNICHAR *)malloc((PATH_MAX + 1) * sizeof (UNICHAR));
90+ if (editor.binaryPathU == NULL)
91+ return false;
92+
93+ editor.binaryPathU[0] = 0;
94+ UNICHAR_GETCWD(editor.binaryPathU, PATH_MAX);
95+
96+ return true;
97+}
98+
8799 int32_t getFileSize(UNICHAR *fileNameU) // returning -1 = filesize over 2GB
88100 {
89101 int64_t fSize;
@@ -173,56 +185,70 @@ static void setupInitialPaths(void) · 83 unmodified lines
173185
174186 #ifdef _WIN32
175187 if (config.modulesPath[0] != '\0')
188+ {
176189 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, config.modulesPath, -1, FReq_ModCurPathU, 80);
190+ FReq_ModCurPathU[80] = 0;
191+ }
177192
178193 if (config.instrPath[0] != '\0')
179194 {
180195 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, config.instrPath, -1, FReq_InsCurPathU, 80);
196+ FReq_InsCurPathU[80] = 0;
181197 insPathSet = true;
182198 }
183199
184200 if (config.samplesPath[0] != '\0')
185201 {
186202 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, config.samplesPath, -1, FReq_SmpCurPathU, 80);
203+ FReq_SmpCurPathU[80] = 0;
187204 smpPathSet = true;
188205 }
189206
190207 if (config.patternsPath[0] != '\0')
191208 {
192209 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, config.patternsPath, -1, FReq_PatCurPathU, 80);
210+ FReq_PatCurPathU[80] = 0;
193211 patPathSet = true;
194212 }
195213
196214 if (config.tracksPath[0] != '\0')
197215 {
198216 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, config.tracksPath, -1, FReq_TrkCurPathU, 80);
217+ FReq_TrkCurPathU[80] = 0;
199218 trkPathSet = true;
200219 }
201220 #else
202221 if (config.modulesPath[0] != '\0')
222+ {
203223 strncpy(FReq_ModCurPathU, config.modulesPath, 80);
224+ FReq_ModCurPathU[80] = 0;
225+ }
204226
205227 if (config.instrPath[0] != '\0')
206228 {
207229 strncpy(FReq_InsCurPathU, config.instrPath, 80);
230+ FReq_InsCurPathU[80] = 0;
208231 insPathSet = true;
209232 }
210233
211234 if (config.samplesPath[0] != '\0')
212235 {
213236 strncpy(FReq_SmpCurPathU, config.samplesPath, 80);
237+ FReq_SmpCurPathU[80] = 0;
214238 smpPathSet = true;
215239 }
216240
217241 if (config.patternsPath[0] != '\0')
218242 {
219243 strncpy(FReq_PatCurPathU, config.patternsPath, 80);
244+ FReq_PatCurPathU[80] = 0;
220245 patPathSet = true;
221246 }
222247
223248 if (config.tracksPath[0] != '\0')
224249 {
225250 strncpy(FReq_TrkCurPathU, config.tracksPath, 80);
251+ FReq_TrkCurPathU[80] = 0;
226252 trkPathSet = true;
227253 }
228254 #endif
@@ -277,28 +303,42 @@ void freeDiskOp(void) · 48 unmodified lines
277303
278304 bool setupDiskOp(void)
279305 {
280− modTmpFName = (char *)calloc(PATH_MAX + 1, sizeof (char));
281− insTmpFName = (char *)calloc(PATH_MAX + 1, sizeof (char));
282− smpTmpFName = (char *)calloc(PATH_MAX + 1, sizeof (char));
283− patTmpFName = (char *)calloc(PATH_MAX + 1, sizeof (char));
284− trkTmpFName = (char *)calloc(PATH_MAX + 1, sizeof (char));
285− FReq_NameTemp = (char *)calloc(PATH_MAX + 1, sizeof (char));
286− FReq_ModCurPathU = (UNICHAR *)calloc(PATH_MAX + 2, sizeof (UNICHAR));
287− FReq_InsCurPathU = (UNICHAR *)calloc(PATH_MAX + 2, sizeof (UNICHAR));
288− FReq_SmpCurPathU = (UNICHAR *)calloc(PATH_MAX + 2, sizeof (UNICHAR));
289− FReq_PatCurPathU = (UNICHAR *)calloc(PATH_MAX + 2, sizeof (UNICHAR));
290− FReq_TrkCurPathU = (UNICHAR *)calloc(PATH_MAX + 2, sizeof (UNICHAR));
291−
292− if (modTmpFName == NULL || insTmpFName == NULL || smpTmpFName == NULL || patTmpFName == NULL ||
293− trkTmpFName == NULL || FReq_NameTemp == NULL || FReq_ModCurPathU == NULL ||
294− FReq_InsCurPathU == NULL || FReq_SmpCurPathU == NULL || FReq_PatCurPathU == NULL ||
295− FReq_TrkCurPathU == NULL)
306+ modTmpFName = (char *)malloc((PATH_MAX + 1) * sizeof (char));
307+ insTmpFName = (char *)malloc((PATH_MAX + 1) * sizeof (char));
308+ smpTmpFName = (char *)malloc((PATH_MAX + 1) * sizeof (char));
309+ patTmpFName = (char *)malloc((PATH_MAX + 1) * sizeof (char));
310+ trkTmpFName = (char *)malloc((PATH_MAX + 1) * sizeof (char));
311+ FReq_NameTemp = (char *)malloc((PATH_MAX + 1) * sizeof (char));
312+
313+ FReq_ModCurPathU = (UNICHAR *)malloc((PATH_MAX + 1) * sizeof (UNICHAR));
314+ FReq_InsCurPathU = (UNICHAR *)malloc((PATH_MAX + 1) * sizeof (UNICHAR));
315+ FReq_SmpCurPathU = (UNICHAR *)malloc((PATH_MAX + 1) * sizeof (UNICHAR));
316+ FReq_PatCurPathU = (UNICHAR *)malloc((PATH_MAX + 1) * sizeof (UNICHAR));
317+ FReq_TrkCurPathU = (UNICHAR *)malloc((PATH_MAX + 1) * sizeof (UNICHAR));
318+
319+ if (modTmpFName == NULL || insTmpFName == NULL || smpTmpFName == NULL ||
320+ patTmpFName == NULL || trkTmpFName == NULL || FReq_NameTemp == NULL ||
321+ FReq_ModCurPathU == NULL || FReq_InsCurPathU == NULL || FReq_SmpCurPathU == NULL ||
322+ FReq_PatCurPathU == NULL || FReq_TrkCurPathU == NULL)
296323 {
297324 // allocated memory is free'd lateron
298325 showErrorMsgBox("Not enough memory!");
299326 return false;
300327 }
301328
329+ // clear first entry of strings
330+ modTmpFName[0] = '\0';
331+ insTmpFName[0] = '\0';
332+ smpTmpFName[0] = '\0';
333+ patTmpFName[0] = '\0';
334+ trkTmpFName[0] = '\0';
335+ FReq_NameTemp[0] = '\0';
336+ FReq_ModCurPathU[0] = 0;
337+ FReq_InsCurPathU[0] = 0;
338+ FReq_SmpCurPathU[0] = 0;
339+ FReq_PatCurPathU[0] = 0;
340+ FReq_TrkCurPathU[0] = 0;
341+
302342 strcpy(modTmpFName, "untitled.xm");
303343 strcpy(insTmpFName, "untitled.xi");
304344 strcpy(smpTmpFName, "untitled.wav");
@@ -602,7 +642,7 @@ void diskOpSetFilename(uint8_t type, UNICHAR *pathU) · 297 unmodified lines
602642 char *filename = getFilenameFromPath(ansiPath);
603643 uint32_t filenameLen = (uint32_t)strlen(filename);
604644
605− if (filenameLen > PATH_MAX-1)
645+ if (filenameLen > PATH_MAX)
606646 {
607647 free(ansiPath);
608648 return; // filename is too long, don't bother to copy it over
@@ -693,9 +733,9 @@ static void openFile(UNICHAR *filenameU, bool songModifiedCheck) · 84 unmodified lines
693733 {
694734 if (songModifiedCheck && song.isModified)
695735 {
696− // remove file selection
736+ // remove file selection before okBox() opens up
697737 FReq_EntrySelected = -1;
698− diskOp_DrawDirectory();
738+ diskOp_DrawFilelist();
699739
700740 if (okBox(2, "System request", "You have unsaved changes in your song. Load new song and lose all changes?") != 1)
701741 return;
@@ -758,8 +798,6 @@ void changeFilenameExt(char *name, char *ext, int32_t nameMaxLen) · 56 unmodified lines
758798 void diskOpChangeFilenameExt(char *ext)
759799 {
760800 changeFilenameExt(FReq_FileName, ext, PATH_MAX);
761− if (ui.diskOpShown)
762− diskOp_DrawDirectory();
763801 }
764802
765803 void trimEntryName(char *name, bool isDir)
@@ -1011,7 +1049,7 @@ static void fileListPressed(int32_t index) · 245 unmodified lines
10111049
10121050 // remove file selection
10131051 FReq_EntrySelected = -1;
1014− diskOp_DrawDirectory();
1052+ diskOp_DrawFilelist();
10151053
10161054 DirRec *dirEntry = &FReq_Buffer[entryIndex];
10171055 switch (mode)
@@ -1077,15 +1115,16 @@ static void fileListPressed(int32_t index) · 59 unmodified lines
10771115 if (nameTmp == NULL)
10781116 break;
10791117
1080− strncpy(FReq_NameTemp, nameTmp, PATH_MAX - 1);
1118+ strncpy(FReq_NameTemp, nameTmp, PATH_MAX);
1119+ FReq_NameTemp[PATH_MAX] = '\0';
10811120 free(nameTmp);
10821121
10831122 // in case of UTF8 -> CP437 encoding failure, there can be question marks. Remove them...
10841123 removeQuestionmarksFromString(FReq_NameTemp);
10851124
1086− if (inputBox(1, dirEntry->isDir ? "Enter new directory name:" : "Enter new filename:", FReq_NameTemp, PATH_MAX - 1) == 1)
1125+ if (inputBox(1, dirEntry->isDir ? "Enter new directory name:" : "Enter new filename:", FReq_NameTemp, PATH_MAX) == 1)
10871126 {
1088− if ((FReq_NameTemp == NULL) || (FReq_NameTemp[0] == '\0'))
1127+ if (FReq_NameTemp == NULL || FReq_NameTemp[0] == '\0')
10891128 {
10901129 okBox(0, "System message", "New name can't be empty!");
10911130 break;
@@ -1120,7 +1159,7 @@ bool testDiskOpMouseDown(bool mouseHeldDlown) · 28 unmodified lines
11201159 if (max > DISKOP_ENTRY_NUM) // needed kludge when mouse-scrolling
11211160 max = DISKOP_ENTRY_NUM;
11221161
1123− if (!mouseHeldDlown)
1162+ if (!mouseHeldDlown) // select file
11241163 {
11251164 FReq_EntrySelected = -1;
11261165
@@ -1130,7 +1169,7 @@ bool testDiskOpMouseDown(bool mouseHeldDlown) · 3 unmodified lines
11301169 if (tmpEntry >= 0 && tmpEntry < max)
11311170 {
11321171 FReq_EntrySelected = tmpEntry;
1133− diskOp_DrawDirectory();
1172+ diskOp_DrawFilelist();
11341173 }
11351174
11361175 mouse.lastUsedObjectType = OBJECT_DISKOPLIST;
@@ -1161,7 +1200,7 @@ bool testDiskOpMouseDown(bool mouseHeldDlown) · 24 unmodified lines
11611200 if (mouse.x < 169 || mouse.x > 331 || mouse.y < 4 || tmpEntry < 0 || tmpEntry >= max)
11621201 {
11631202 FReq_EntrySelected = -1;
1164− diskOp_DrawDirectory();
1203+ diskOp_DrawFilelist();
11651204
11661205 return true;
11671206 }
@@ -1169,7 +1208,7 @@ bool testDiskOpMouseDown(bool mouseHeldDlown) · 1 unmodified line
11691208 if (tmpEntry != FReq_EntrySelected)
11701209 {
11711210 FReq_EntrySelected = tmpEntry;
1172− diskOp_DrawDirectory();
1211+ diskOp_DrawFilelist();
11731212 }
11741213
11751214 return true;
@@ -1183,7 +1222,7 @@ void testDiskOpMouseRelease(void) · 7 unmodified lines
11831222 fileListPressed((mouse.y - 4) / (FONT1_CHAR_H + 1));
11841223
11851224 FReq_EntrySelected = -1;
1186− diskOp_DrawDirectory();
1225+ diskOp_DrawFilelist();
11871226 }
11881227 }
11891228
@@ -1537,7 +1576,7 @@ static char *ach(int32_t rad) // used for sortDirectory() · 347 unmodified lines
15371576 return NULL;
15381577 }
15391578
1540− char *p = (char *)malloc(nameLen + 2);
1579+ char *p = (char *)malloc(nameLen+1+1);
15411580 if (p == NULL)
15421581 {
15431582 free(name);
@@ -1701,6 +1740,9 @@ static void displayCurrPath(void) · 157 unmodified lines
17011740 {
17021741 fillRect(4, 145, 162, 10, PAL_DESKTOP);
17031742
1743+ if (FReq_CurPathU == NULL)
1744+ return;
1745+
17041746 const uint32_t pathLen = (uint32_t)UNICHAR_STRLEN(FReq_CurPathU);
17051747 if (pathLen == 0)
17061748 return;
@@ -1722,11 +1764,14 @@ static void displayCurrPath(void) · 15 unmodified lines
17221764 {
17231765 // path doesn't fit, print drive + ".." + last directory
17241766
1725− memset(FReq_NameTemp, 0, PATH_MAX + 1);
17261767 #ifdef _WIN32
1727− strncpy(FReq_NameTemp, p, 3);
1768+ memcpy(FReq_NameTemp, p, 3); // get drive (f.ex. C:\)
1769+ FReq_NameTemp[3] = '\0';
1770+
17281771 strcat(FReq_NameTemp, ".\001"); // special character in font
1772+ FReq_NameTemp[5] = '\0';
17291773 #else
1774+ FReq_NameTemp[0] = '\0';
17301775 strcpy(FReq_NameTemp, "/");
17311776 strcat(FReq_NameTemp, "..");
17321777 #endif
@@ -1735,7 +1780,7 @@ static void displayCurrPath(void) · 2 unmodified lines
17351780 if (delimiter != NULL)
17361781 {
17371782 #ifdef _WIN32
1738− strcat(FReq_NameTemp, delimiter + 1);
1783+ strcat(FReq_NameTemp, delimiter+1);
17391784 #else
17401785 strcat(FReq_NameTemp, delimiter);
17411786 #endif
@@ -1749,9 +1794,9 @@ static void displayCurrPath(void) · 7 unmodified lines
17491794 p = FReq_NameTemp;
17501795 while (j >= 6 && textWidth(p) >= 162)
17511796 {
1752− p[j - 2] = '.';
1753− p[j - 1] = '.';
1754− p[j - 0] = '\0';
1797+ p[j-2] = '.';
1798+ p[j-1] = '.';
1799+ p[j-0] = '\0';
17551800 j--;
17561801 }
17571802 }
@@ -1762,25 +1807,20 @@ static void displayCurrPath(void) · 4 unmodified lines
17621807 free(asciiPath);
17631808 }
17641809
1765−void diskOp_DrawDirectory(void)
1810+void diskOp_DrawFilelist(void)
17661811 {
1767− clearRect(FILENAME_TEXT_X - 1, 4, 162, 164);
1768− drawTextBox(TB_DISKOP_FILENAME);
1812+ clearRect(FILENAME_TEXT_X-1, 4, 162, 164);
17691813
1814+ if (FReq_FileCount == 0)
1815+ return;
1816+
1817+ // draw "selected file" rectangle
17701818 if (FReq_EntrySelected != -1)
17711819 {
17721820 const uint16_t y = 4 + (uint16_t)((FONT1_CHAR_H + 1) * FReq_EntrySelected);
17731821 fillRect(FILENAME_TEXT_X - 1, y, 162, FONT1_CHAR_H, PAL_PATTEXT);
17741822 }
17751823
1776− displayCurrPath();
1777−#ifdef _WIN32
1778− setupDiskOpDrives();
1779−#endif
1780−
1781− if (FReq_FileCount == 0)
1782− return;
1783−
17841824 for (uint16_t i = 0; i < DISKOP_ENTRY_NUM; i++)
17851825 {
17861826 const int32_t bufEntry = FReq_DirPos + i;
@@ -1817,9 +1857,21 @@ void diskOp_DrawDirectory(void) · 30 unmodified lines
18171857 if (!FReq_Buffer[bufEntry].isDir)
18181858 printFormattedFilesize(FILESIZE_TEXT_X, y, bufEntry);
18191859 }
1860+}
1861+
1862+void diskOp_DrawDirectory(void)
1863+{
1864+ drawTextBox(TB_DISKOP_FILENAME);
1865+
1866+ displayCurrPath();
1867+#ifdef _WIN32
1868+ setupDiskOpDrives();
1869+#endif
18201870
1821− setScrollBarPos(SB_DISKOP_LIST, FReq_DirPos, true);
18221871 setScrollBarEnd(SB_DISKOP_LIST, FReq_FileCount);
1872+ setScrollBarPos(SB_DISKOP_LIST, FReq_DirPos, false);
1873+
1874+ diskOp_DrawFilelist();
18231875 }
18241876
18251877 static DirRec *bufferCreateEmptyDir(void) // special case: creates a dir entry with a ".." directory
@@ -2035,7 +2087,7 @@ static void setDiskOpItem(uint8_t item) · 209 unmodified lines
20352087 // FReq_ModCurPathU is always set at this point
20362088
20372089 FReq_CurPathU = FReq_ModCurPathU;
2038− if (FReq_CurPathU != NULL)
2090+ if (FReq_CurPathU != NULL && FReq_CurPathU[0] != '\0')
20392091 UNICHAR_CHDIR(FReq_CurPathU);
20402092 }
20412093 break;
@@ -2044,7 +2096,7 @@ static void setDiskOpItem(uint8_t item) · 2 unmodified lines
20442096 {
20452097 FReq_FileName = insTmpFName;
20462098
2047− if (!insPathSet)
2099+ if (!insPathSet && FReq_CurPathU != NULL && FReq_CurPathU[0] != '\0')
20482100 {
20492101 UNICHAR_STRCPY(FReq_InsCurPathU, FReq_CurPathU);
20502102 insPathSet = true;
@@ -2060,7 +2112,7 @@ static void setDiskOpItem(uint8_t item) · 9 unmodified lines
20602112 {
20612113 FReq_FileName = smpTmpFName;
20622114
2063− if (!smpPathSet)
2115+ if (!smpPathSet && FReq_CurPathU != NULL && FReq_CurPathU[0] != '\0')
20642116 {
20652117 UNICHAR_STRCPY(FReq_SmpCurPathU, FReq_CurPathU);
20662118 smpPathSet = true;
@@ -2076,7 +2128,7 @@ static void setDiskOpItem(uint8_t item) · 9 unmodified lines
20762128 {
20772129 FReq_FileName = patTmpFName;
20782130
2079− if (!patPathSet)
2131+ if (!patPathSet && FReq_CurPathU != NULL && FReq_CurPathU[0] != '\0')
20802132 {
20812133 UNICHAR_STRCPY(FReq_PatCurPathU, FReq_CurPathU);
20822134 patPathSet = true;
@@ -2092,7 +2144,7 @@ static void setDiskOpItem(uint8_t item) · 9 unmodified lines
20922144 {
20932145 FReq_FileName = trkTmpFName;
20942146
2095− if (!trkPathSet)
2147+ if (!trkPathSet && FReq_CurPathU != NULL && FReq_CurPathU[0] != '\0')
20962148 {
20972149 UNICHAR_STRCPY(FReq_TrkCurPathU, FReq_CurPathU);
20982150 trkPathSet = true;
@@ -2105,15 +2157,13 @@ static void setDiskOpItem(uint8_t item) · 6 unmodified lines
21052157 break;
21062158 }
21072159
2108− const int32_t pathLen = (int32_t)UNICHAR_STRLEN(FReq_CurPathU);
2109− if (pathLen == 0 && FReq_ModCurPathU[0] != '\0')
2160+ if (FReq_CurPathU != NULL && FReq_ModCurPathU != NULL)
21102161 {
2111− memset(FReq_CurPathU, 0, (PATH_MAX + 2) * sizeof (UNICHAR));
2112− UNICHAR_STRCPY(FReq_CurPathU, FReq_ModCurPathU);
2162+ if (FReq_CurPathU[0] == '\0' && FReq_ModCurPathU[0] != '\0')
2163+ UNICHAR_STRCPY(FReq_CurPathU, FReq_ModCurPathU);
21132164 }
21142165
21152166 textBoxes[TB_DISKOP_FILENAME].textPtr = FReq_FileName;
2116−
21172167 FReq_ShowAllFiles = false;
21182168
21192169 if (ui.diskOpShown)
@@ -2199,14 +2249,15 @@ void showDiskOpScreen(void) · 79 unmodified lines
21992249 assert(FReq_ModCurPathU != NULL);
22002250
22012251 // first test if we can change the dir to the one stored in the config (if present)
2202− if (UNICHAR_STRLEN(FReq_ModCurPathU) == 0 || UNICHAR_CHDIR(FReq_ModCurPathU) != 0)
2252+ if (FReq_ModCurPathU[0] == '\0' || UNICHAR_CHDIR(FReq_ModCurPathU) != 0)
22032253 {
22042254 // nope, couldn't do that, set Disk Op. path to user/home directory
22052255 #ifdef _WIN32
22062256 SHGetFolderPathW(NULL, CSIDL_PROFILE, NULL, 0, FReq_ModCurPathU);
22072257 #else
2208− if (getenv("HOME") != NULL)
2209− UNICHAR_STRCPY(FReq_ModCurPathU, getenv("HOME"));
2258+ char *home = getenv("HOME");
2259+ if (home != NULL)
2260+ UNICHAR_STRCPY(FReq_ModCurPathU, home);
22102261 #endif
22112262 UNICHAR_CHDIR(FReq_ModCurPathU);
22122263 }
@@ -2285,7 +2336,7 @@ void sbDiskOpSetPos(uint32_t pos) · 72 unmodified lines
22852336 if ((int32_t)pos != FReq_DirPos && FReq_FileCount > DISKOP_ENTRY_NUM)
22862337 {
22872338 FReq_DirPos = (int32_t)pos;
2288− diskOp_DrawDirectory();
2339+ diskOp_DrawFilelist();
22892340 }
22902341 }
22912342
@@ -2345,7 +2396,7 @@ void pbDiskOpRename(void) · 53 unmodified lines
23452396 void pbDiskOpMakeDir(void)
23462397 {
23472398 FReq_NameTemp[0] = '\0';
2348− if (inputBox(1, "Enter directory name:", FReq_NameTemp, PATH_MAX - 1) == 1)
2399+ if (inputBox(1, "Enter directory name:", FReq_NameTemp, PATH_MAX) == 1)
23492400 {
23502401 if (FReq_NameTemp[0] == '\0')
23512402 {
@@ -2371,7 +2422,7 @@ void pbDiskOpRefresh(void) · 19 unmodified lines
23712422 void pbDiskOpSetPath(void)
23722423 {
23732424 FReq_NameTemp[0] = '\0';
2374− if (inputBox(1, "Enter new directory path:", FReq_NameTemp, PATH_MAX - 1) == 1)
2425+ if (inputBox(1, "Enter new directory path:", FReq_NameTemp, PATH_MAX) == 1)
23752426 {
23762427 if (FReq_NameTemp[0] == '\0')
23772428 {
src/ft2_diskop.h+2−0
@@ -21,6 +21,7 @@ enum · 20 unmodified lines
2121 SMP_SAVE_MODE_WAV = 2
2222 };
2323
24+bool setupExecutablePath(void);
2425 int32_t getFileSize(UNICHAR *fileNameU);
2526 uint8_t getDiskOpItem(void);
2627 void updateCurrSongFilename(void); // for window title
@@ -41,6 +42,7 @@ int32_t getExtOffset(char *s, int32_t stringLen); // get byte offset of file ext · 14 unmodified lines
4142 bool testDiskOpMouseDown(bool mouseHeldDown);
4243 void testDiskOpMouseRelease(void);
4344 void diskOp_StartDirReadThread(void);
45+void diskOp_DrawFilelist(void);
4446 void diskOp_DrawDirectory(void);
4547 void showDiskOpScreen(void);
4648 void hideDiskOpScreen(void);
src/ft2_events.c+4−3
@@ -35,13 +35,14 @@ · 34 unmodified lines
3535
3636 #define CRASH_TEXT "Oh no!\nThe Fasttracker II clone has crashed...\n\nA backup .xm was hopefully " \
3737 "saved to the current module directory.\n\nPlease report this bug if you can.\n" \
38− "Try to mention what you did before the crash happened."
38+ "Try to mention what you did before the crash happened.\n" \
39+ "My email can be found at the bottom of 16-bits.org."
3940
4041 static bool backupMadeAfterCrash;
4142
4243 #ifdef _WIN32
43−#define SYSMSG_FILE_ARG (WM_USER + 1)
44−#define ARGV_SHARED_MEM_MAX_LEN ((MAX_PATH * 2) + 2)
44+#define SYSMSG_FILE_ARG (WM_USER+1)
45+#define ARGV_SHARED_MEM_MAX_LEN ((PATH_MAX+1) * sizeof (WCHAR))
4546 #define SHARED_HWND_NAME TEXT("Local\\FT2CloneHwnd")
4647 #define SHARED_FILENAME TEXT("Local\\FT2CloneFilename")
4748 static HWND hWnd;
src/ft2_gui.c+10−9
@@ -127,20 +127,21 @@ void unstuckLastUsedGUIElement(void) · 126 unmodified lines
127127
128128 bool setupGUI(void)
129129 {
130− int32_t i;
131−
132130 // all memory will be NULL-tested and free'd if we return false somewhere in this function
133131
134− editor.tmpFilenameU = (UNICHAR *)calloc(PATH_MAX + 1, sizeof (UNICHAR));
135− editor.tmpInstrFilenameU = (UNICHAR *)calloc(PATH_MAX + 1, sizeof (UNICHAR));
132+ editor.tmpFilenameU = (UNICHAR *)malloc((PATH_MAX + 1) * sizeof (UNICHAR));
133+ editor.tmpInstrFilenameU = (UNICHAR *)malloc((PATH_MAX + 1) * sizeof (UNICHAR));
136134
137135 if (editor.tmpFilenameU == NULL || editor.tmpInstrFilenameU == NULL)
138136 goto setupGUI_OOM;
139137
138+ editor.tmpFilenameU[0] = 0;
139+ editor.tmpInstrFilenameU[0] = 0;
140+
140141 // set uninitialized GUI struct entries
141142
142143 textBox_t *t = &textBoxes[1]; // skip first entry, it's reserved for inputBox())
143− for (i = 1; i < NUM_TEXTBOXES; i++, t++)
144+ for (int32_t i = 1; i < NUM_TEXTBOXES; i++, t++)
144145 {
145146 t->visible = false;
146147 t->bufOffset = 0;
@@ -156,7 +157,7 @@ bool setupGUI(void) · 9 unmodified lines
156157 }
157158
158159 pushButton_t *p = pushButtons;
159− for (i = 0; i < NUM_PUSHBUTTONS; i++, p++)
160+ for (int32_t i = 0; i < NUM_PUSHBUTTONS; i++, p++)
160161 {
161162 p->state = 0;
162163 p->visible = false;
@@ -174,7 +175,7 @@ bool setupGUI(void) · 11 unmodified lines
174175 }
175176
176177 checkBox_t *c = checkBoxes;
177− for (i = 0; i < NUM_CHECKBOXES; i++, c++)
178+ for (int32_t i = 0; i < NUM_CHECKBOXES; i++, c++)
178179 {
179180 c->state = 0;
180181 c->checked = false;
@@ -182,14 +183,14 @@ bool setupGUI(void) · 1 unmodified line
182183 }
183184
184185 radioButton_t *r = radioButtons;
185− for (i = 0; i < NUM_RADIOBUTTONS; i++, r++)
186+ for (int32_t i = 0; i < NUM_RADIOBUTTONS; i++, r++)
186187 {
187188 r->state = 0;
188189 r->visible = false;
189190 }
190191
191192 scrollBar_t *s = scrollBars;
192− for (i = 0; i < NUM_SCROLLBARS; i++, s++)
193+ for (int32_t i = 0; i < NUM_SCROLLBARS; i++, s++)
193194 {
194195 s->visible = false;
195196 s->state = 0;
src/ft2_keyboard.c+125−42
@@ -122,7 +122,8 @@ void keyDownHandler(SDL_Scancode scancode, SDL_Keycode keycode, bool keyWasRepea · 121 unmodified lines
122122 return; // do NOT repeat keys in Nibbles or if keyRepeat is disabled
123123 }
124124
125− keyb.keyRepeat = true;
125+ if (scancode != SDL_SCANCODE_ESCAPE)
126+ keyb.keyRepeat = true;
126127
127128 // handle certain keys (home/end/left/right etc) when editing text
128129 if (editor.editTextFlag)
@@ -669,6 +670,7 @@ static bool checkModifiedKeys(SDL_Keycode keycode) · 540 unmodified lines
669670
670671 case SDLK_KP_ENTER:
671672 case SDLK_RETURN:
673+ {
672674 if (keyb.leftAltPressed)
673675 {
674676 toggleFullScreen();
@@ -679,9 +681,11 @@ static bool checkModifiedKeys(SDL_Keycode keycode) · 4 unmodified lines
679681 #endif
680682 return true;
681683 }
682− break;
684+ }
685+ break;
683686
684687 case SDLK_F9:
688+ {
685689 if (keyb.leftCtrlPressed)
686690 {
687691 startPlaying(PLAYMODE_PATT, editor.ptnJumpPos[0]);
@@ -692,9 +696,11 @@ static bool checkModifiedKeys(SDL_Keycode keycode) · 4 unmodified lines
692696 editor.ptnJumpPos[0] = (uint8_t)editor.pattPos;
693697 return true;
694698 }
695− break;
699+ }
700+ break;
696701
697702 case SDLK_F10:
703+ {
698704 if (keyb.leftCtrlPressed)
699705 {
700706 startPlaying(PLAYMODE_PATT, editor.ptnJumpPos[1]);
@@ -705,9 +711,11 @@ static bool checkModifiedKeys(SDL_Keycode keycode) · 4 unmodified lines
705711 editor.ptnJumpPos[1] = (uint8_t)editor.pattPos;
706712 return true;
707713 }
708− break;
714+ }
715+ break;
709716
710717 case SDLK_F11:
718+ {
711719 if (keyb.leftCtrlPressed)
712720 {
713721 startPlaying(PLAYMODE_PATT, editor.ptnJumpPos[2]);
@@ -718,9 +726,11 @@ static bool checkModifiedKeys(SDL_Keycode keycode) · 4 unmodified lines
718726 editor.ptnJumpPos[2] = (uint8_t)editor.pattPos;
719727 return true;
720728 }
721− break;
729+ }
730+ break;
722731
723732 case SDLK_F12:
733+ {
724734 if (keyb.leftCtrlPressed)
725735 {
726736 startPlaying(PLAYMODE_PATT, editor.ptnJumpPos[3]);
@@ -731,9 +741,11 @@ static bool checkModifiedKeys(SDL_Keycode keycode) · 4 unmodified lines
731741 editor.ptnJumpPos[3] = (uint8_t)editor.pattPos;
732742 return true;
733743 }
734− break;
744+ }
745+ break;
735746
736747 case SDLK_a:
748+ {
737749 if (keyb.leftCtrlPressed)
738750 {
739751 if (ui.sampleEditorShown)
@@ -752,9 +764,11 @@ static bool checkModifiedKeys(SDL_Keycode keycode) · 12 unmodified lines
752764
753765 return true;
754766 }
755− break;
767+ }
768+ break;
756769
757770 case SDLK_b:
771+ {
758772 if (keyb.leftCtrlPressed)
759773 {
760774 if (!ui.aboutScreenShown)
@@ -762,9 +776,11 @@ static bool checkModifiedKeys(SDL_Keycode keycode) · 1 unmodified line
762776
763777 return true;
764778 }
765− break;
779+ }
780+ break;
766781
767782 case SDLK_c:
783+ {
768784 if (keyb.leftAltPressed)
769785 {
770786 if (ui.sampleEditorShown)
@@ -793,9 +809,11 @@ static bool checkModifiedKeys(SDL_Keycode keycode) · 22 unmodified lines
793809
794810 return true;
795811 }
796− break;
812+ }
813+ break;
797814
798815 case SDLK_d:
816+ {
799817 if (keyb.leftAltPressed)
800818 {
801819 jumpToChannel(10);
@@ -808,9 +826,11 @@ static bool checkModifiedKeys(SDL_Keycode keycode) · 6 unmodified lines
808826
809827 return true;
810828 }
811− break;
829+ }
830+ break;
812831
813832 case SDLK_e:
833+ {
814834 if (keyb.leftAltPressed)
815835 {
816836 jumpToChannel(2);
@@ -826,9 +846,11 @@ static bool checkModifiedKeys(SDL_Keycode keycode) · 9 unmodified lines
826846 showSampleEditorExt();
827847 return true;
828848 }
829− break;
849+ }
850+ break;
830851
831852 case SDLK_f:
853+ {
832854 #ifdef __APPLE__
833855 if (keyb.leftCommandPressed && keyb.leftCtrlPressed)
834856 {
@@ -854,17 +876,21 @@ static bool checkModifiedKeys(SDL_Keycode keycode) · 19 unmodified lines
854876 jumpToChannel(11);
855877 return true;
856878 }
857− break;
879+ }
880+ break;
858881
859882 case SDLK_g:
883+ {
860884 if (keyb.leftAltPressed)
861885 {
862886 jumpToChannel(12);
863887 return true;
864888 }
865− break;
889+ }
890+ break;
866891
867892 case SDLK_h:
893+ {
868894 if (keyb.leftAltPressed)
869895 {
870896 jumpToChannel(13);
@@ -875,9 +901,11 @@ static bool checkModifiedKeys(SDL_Keycode keycode) · 4 unmodified lines
875901 showHelpScreen();
876902 return true;
877903 }
878− break;
904+ }
905+ break;
879906
880907 case SDLK_i:
908+ {
881909 if (keyb.leftAltPressed)
882910 {
883911 jumpToChannel(7);
@@ -888,25 +916,31 @@ static bool checkModifiedKeys(SDL_Keycode keycode) · 4 unmodified lines
888916 showInstEditor();
889917 return true;
890918 }
891− break;
919+ }
920+ break;
892921
893922 case SDLK_j:
923+ {
894924 if (keyb.leftAltPressed)
895925 {
896926 jumpToChannel(14);
897927 return true;
898928 }
899− break;
929+ }
930+ break;
900931
901932 case SDLK_k:
933+ {
902934 if (keyb.leftAltPressed)
903935 {
904936 jumpToChannel(15);
905937 return true;
906938 }
907− break;
939+ }
940+ break;
908941
909942 case SDLK_m:
943+ {
910944 if (keyb.leftCtrlPressed)
911945 {
912946 if (ui.aboutScreenShown) hideAboutScreen();
@@ -918,17 +952,21 @@ static bool checkModifiedKeys(SDL_Keycode keycode) · 5 unmodified lines
918952
919953 return true;
920954 }
921− break;
955+ }
956+ break;
922957
923958 case SDLK_n:
959+ {
924960 if (keyb.leftCtrlPressed)
925961 {
926962 showNibblesScreen();
927963 return true;
928964 }
929− break;
965+ }
966+ break;
930967
931968 case SDLK_p:
969+ {
932970 if (keyb.leftCtrlPressed)
933971 {
934972 if (!ui.patternEditorShown)
@@ -942,17 +980,21 @@ static bool checkModifiedKeys(SDL_Keycode keycode) · 7 unmodified lines
942980
943981 return true;
944982 }
945− break;
983+ }
984+ break;
946985
947986 case SDLK_q:
987+ {
948988 if (keyb.leftAltPressed)
949989 {
950990 jumpToChannel(0);
951991 return true;
952992 }
953− break;
993+ }
994+ break;
954995
955996 case SDLK_r:
997+ {
956998 if (keyb.leftAltPressed)
957999 {
9581000 if (ui.sampleEditorShown)
@@ -967,9 +1009,11 @@ static bool checkModifiedKeys(SDL_Keycode keycode) · 8 unmodified lines
9671009 showTrimScreen();
9681010 return true;
9691011 }
970− break;
1012+ }
1013+ break;
9711014
9721015 case SDLK_s:
1016+ {
9731017 if (keyb.leftAltPressed)
9741018 {
9751019 if (ui.sampleEditorShown)
@@ -984,9 +1028,11 @@ static bool checkModifiedKeys(SDL_Keycode keycode) · 8 unmodified lines
9841028 showSampleEditor();
9851029 return true;
9861030 }
987− break;
1031+ }
1032+ break;
9881033
9891034 case SDLK_t:
1035+ {
9901036 if (keyb.leftAltPressed)
9911037 {
9921038 jumpToChannel(4);
@@ -997,17 +1043,21 @@ static bool checkModifiedKeys(SDL_Keycode keycode) · 4 unmodified lines
9971043 showTranspose();
9981044 return true;
9991045 }
1000− break;
1046+ }
1047+ break;
10011048
10021049 case SDLK_u:
1050+ {
10031051 if (keyb.leftAltPressed)
10041052 {
10051053 jumpToChannel(6);
10061054 return true;
10071055 }
1008− break;
1056+ }
1057+ break;
10091058
10101059 case SDLK_v:
1060+ {
10111061 if (keyb.leftAltPressed)
10121062 {
10131063 if (ui.sampleEditorShown)
@@ -1036,17 +1086,21 @@ static bool checkModifiedKeys(SDL_Keycode keycode) · 22 unmodified lines
10361086
10371087 return true;
10381088 }
1039− break;
1089+ }
1090+ break;
10401091
10411092 case SDLK_w:
1093+ {
10421094 if (keyb.leftAltPressed)
10431095 {
10441096 jumpToChannel(1);
10451097 return true;
10461098 }
1047− break;
1099+ }
1100+ break;
10481101
10491102 case SDLK_x:
1103+ {
10501104 if (keyb.leftAltPressed)
10511105 {
10521106 if (ui.sampleEditorShown)
@@ -1080,17 +1134,21 @@ static bool checkModifiedKeys(SDL_Keycode keycode) · 27 unmodified lines
10801134
10811135 return true;
10821136 }
1083− break;
1137+ }
1138+ break;
10841139
10851140 case SDLK_y:
1141+ {
10861142 if (keyb.leftAltPressed)
10871143 {
10881144 jumpToChannel(5);
10891145 return true;
10901146 }
1091− break;
1147+ }
1148+ break;
10921149
10931150 case SDLK_z:
1151+ {
10941152 if (keyb.leftAltPressed)
10951153 {
10961154 if (ui.sampleEditorShown)
@@ -1103,9 +1161,11 @@ static bool checkModifiedKeys(SDL_Keycode keycode) · 6 unmodified lines
11031161 togglePatternEditorExtended();
11041162 return true;
11051163 }
1106− break;
1164+ }
1165+ break;
11071166
11081167 case SDLK_1:
1168+ {
11091169 if (keyb.leftAltPressed)
11101170 {
11111171 if (keyb.leftShiftPressed)
@@ -1123,9 +1183,11 @@ static bool checkModifiedKeys(SDL_Keycode keycode) · 11 unmodified lines
11231183
11241184 return true;
11251185 }
1126− break;
1186+ }
1187+ break;
11271188
11281189 case SDLK_2:
1190+ {
11291191 if (keyb.leftAltPressed)
11301192 {
11311193 if (keyb.leftShiftPressed)
@@ -1143,9 +1205,11 @@ static bool checkModifiedKeys(SDL_Keycode keycode) · 11 unmodified lines
11431205
11441206 return true;
11451207 }
1146− break;
1208+ }
1209+ break;
11471210
11481211 case SDLK_3:
1212+ {
11491213 if (keyb.leftAltPressed)
11501214 {
11511215 if (keyb.leftShiftPressed)
@@ -1163,9 +1227,11 @@ static bool checkModifiedKeys(SDL_Keycode keycode) · 11 unmodified lines
11631227
11641228 return true;
11651229 }
1166− break;
1230+ }
1231+ break;
11671232
11681233 case SDLK_4:
1234+ {
11691235 if (keyb.leftAltPressed)
11701236 {
11711237 if (keyb.leftShiftPressed)
@@ -1185,9 +1251,11 @@ static bool checkModifiedKeys(SDL_Keycode keycode) · 13 unmodified lines
11851251 return true;
11861252 }
11871253 #endif
1188− break;
1254+ }
1255+ break;
11891256
11901257 case SDLK_5:
1258+ {
11911259 if (keyb.leftAltPressed)
11921260 {
11931261 if (keyb.leftShiftPressed)
@@ -1197,9 +1265,11 @@ static bool checkModifiedKeys(SDL_Keycode keycode) · 3 unmodified lines
11971265
11981266 return true;
11991267 }
1200− break;
1268+ }
1269+ break;
12011270
12021271 case SDLK_6:
1272+ {
12031273 if (keyb.leftAltPressed)
12041274 {
12051275 if (keyb.leftShiftPressed)
@@ -1209,9 +1279,11 @@ static bool checkModifiedKeys(SDL_Keycode keycode) · 3 unmodified lines
12091279
12101280 return true;
12111281 }
1212− break;
1282+ }
1283+ break;
12131284
12141285 case SDLK_7:
1286+ {
12151287 if (keyb.leftAltPressed)
12161288 {
12171289 if (keyb.leftShiftPressed)
@@ -1221,9 +1293,11 @@ static bool checkModifiedKeys(SDL_Keycode keycode) · 3 unmodified lines
12211293
12221294 return true;
12231295 }
1224− break;
1296+ }
1297+ break;
12251298
12261299 case SDLK_8:
1300+ {
12271301 if (keyb.leftAltPressed)
12281302 {
12291303 if (keyb.leftShiftPressed)
@@ -1233,9 +1307,11 @@ static bool checkModifiedKeys(SDL_Keycode keycode) · 3 unmodified lines
12331307
12341308 return true;
12351309 }
1236− break;
1310+ }
1311+ break;
12371312
12381313 case SDLK_9:
1314+ {
12391315 if (keyb.leftAltPressed)
12401316 {
12411317 if (keyb.leftShiftPressed)
@@ -1245,9 +1321,11 @@ static bool checkModifiedKeys(SDL_Keycode keycode) · 3 unmodified lines
12451321
12461322 return true;
12471323 }
1248− break;
1324+ }
1325+ break;
12491326
12501327 case SDLK_0:
1328+ {
12511329 if (keyb.leftAltPressed)
12521330 {
12531331 if (keyb.leftShiftPressed)
@@ -1257,9 +1335,11 @@ static bool checkModifiedKeys(SDL_Keycode keycode) · 3 unmodified lines
12571335
12581336 return true;
12591337 }
1260− break;
1338+ }
1339+ break;
12611340
12621341 case SDLK_LEFT:
1342+ {
12631343 if (keyb.leftShiftPressed)
12641344 {
12651345 decSongPos();
@@ -1275,9 +1355,11 @@ static bool checkModifiedKeys(SDL_Keycode keycode) · 9 unmodified lines
12751355 keybPattMarkLeft();
12761356 return true;
12771357 }
1278− break;
1358+ }
1359+ break;
12791360
12801361 case SDLK_RIGHT:
1362+ {
12811363 if (keyb.leftShiftPressed)
12821364 {
12831365 incSongPos();
@@ -1293,7 +1375,8 @@ static bool checkModifiedKeys(SDL_Keycode keycode) · 9 unmodified lines
12931375 keybPattMarkRight();
12941376 return true;
12951377 }
1296− break;
1378+ }
1379+ break;
12971380 }
12981381
12991382 return false;
src/ft2_main.c+16−12
@@ -147,9 +147,7 @@ int main(int argc, char *argv[]) · 146 unmodified lines
147147 #ifdef __APPLE__
148148 osxSetDirToProgramDirFromArgs(argv);
149149 #endif
150− UNICHAR_GETCWD(editor.binaryPathU, PATH_MAX);
151−
152− if (!loadBMPs())
150+ if (!setupExecutablePath() || !loadBMPs())
153151 {
154152 cleanUpAndExit();
155153 return 1;
@@ -351,22 +349,28 @@ static void cleanUpAndExit(void) // never call this inside the main loop! · 195 unmodified lines
351349 }
352350 #endif
353351
354− if (editor.audioDevConfigFileLocation != NULL)
352+ if (editor.audioDevConfigFileLocationU != NULL)
353+ {
354+ free(editor.audioDevConfigFileLocationU);
355+ editor.audioDevConfigFileLocationU = NULL;
356+ }
357+
358+ if (editor.configFileLocationU != NULL)
355359 {
356− free(editor.audioDevConfigFileLocation);
357− editor.audioDevConfigFileLocation = NULL;
360+ free(editor.configFileLocationU);
361+ editor.configFileLocationU = NULL;
358362 }
359363
360− if (editor.configFileLocation != NULL)
364+ if (editor.midiConfigFileLocationU != NULL)
361365 {
362− free(editor.configFileLocation);
363− editor.configFileLocation = NULL;
366+ free(editor.midiConfigFileLocationU);
367+ editor.midiConfigFileLocationU = NULL;
364368 }
365369
366− if (editor.midiConfigFileLocation != NULL)
370+ if (editor.binaryPathU != NULL)
367371 {
368− free(editor.midiConfigFileLocation);
369− editor.midiConfigFileLocation = NULL;
372+ free(editor.binaryPathU);
373+ editor.binaryPathU = NULL;
370374 }
371375
372376 #ifdef _WIN32
src/ft2_midi.c+7−5
@@ -18,6 +18,8 @@ · 17 unmodified lines
1818 #include "ft2_structs.h"
1919 #include "rtmidi/rtmidi_c.h"
2020
21+#define MAX_DEV_STR_LEN 256
22+
2123 // hide POSIX warnings
2224 #ifdef _MSC_VER
2325 #pragma warning(disable: 4996)
@@ -265,7 +267,7 @@ bool saveMidiInputDeviceToConfig(void) · 241 unmodified lines
265267 if (midiInStr == NULL)
266268 return false;
267269
268− FILE *f = UNICHAR_FOPEN(editor.midiConfigFileLocation, "w");
270+ FILE *f = UNICHAR_FOPEN(editor.midiConfigFileLocationU, "w");
269271 if (f == NULL)
270272 {
271273 free(midiInStr);
@@ -281,8 +283,6 @@ bool saveMidiInputDeviceToConfig(void) · 9 unmodified lines
281283
282284 bool setMidiInputDeviceFromConfig(void)
283285 {
284−#define MAX_DEV_STR_LEN 1024
285−
286286 uint32_t i;
287287
288288 if (midi.inputDeviceName != NULL)
@@ -292,17 +292,19 @@ bool setMidiInputDeviceFromConfig(void) · 3 unmodified lines
292292 if (numDevices == 0)
293293 goto setDefMidiInputDev;
294294
295− FILE *f = UNICHAR_FOPEN(editor.midiConfigFileLocation, "r");
295+ FILE *f = UNICHAR_FOPEN(editor.midiConfigFileLocationU, "r");
296296 if (f == NULL)
297297 goto setDefMidiInputDev;
298298
299− char *devString = (char *)calloc(MAX_DEV_STR_LEN+4, sizeof (char));
299+ char *devString = (char *)malloc((MAX_DEV_STR_LEN+4) * sizeof (char));
300300 if (devString == NULL)
301301 {
302302 fclose(f);
303303 goto setDefMidiInputDev;
304304 }
305305
306+ devString[0] = '\0';
307+
306308 if (fgets(devString, MAX_DEV_STR_LEN, f) == NULL)
307309 {
308310 fclose(f);
src/ft2_module_loader.c+23−8
@@ -526,9 +526,7 @@ static void setupLoadedModule(void) · 525 unmodified lines
526526
527527 bool handleModuleLoadFromArg(int argc, char **argv)
528528 {
529− UNICHAR tmpPathU[PATH_MAX+2];
530−
531− // this is crude, we always expect only one parameter, and that it is the module.
529+ // we always expect only one parameter, and that it is the module
532530
533531 if (argc != 2 || argv[1] == NULL || argv[1][0] == '\0')
534532 return false;
@@ -540,15 +538,26 @@ bool handleModuleLoadFromArg(int argc, char **argv) · 5 unmodified lines
540538
541539 const uint32_t filenameLen = (const uint32_t)strlen(argv[1]);
542540
543− UNICHAR *filenameU = (UNICHAR *)calloc(filenameLen+1, sizeof (UNICHAR));
541+ UNICHAR *tmpPathU = (UNICHAR *)malloc((PATH_MAX + 1) * sizeof (UNICHAR));
542+ if (tmpPathU == NULL)
543+ {
544+ okBox(0, "System message", "Not enough memory!");
545+ return false;
546+ }
547+
548+ UNICHAR *filenameU = (UNICHAR *)malloc((filenameLen + 1) * sizeof (UNICHAR));
544549 if (filenameU == NULL)
545550 {
551+ free(tmpPathU);
546552 okBox(0, "System message", "Not enough memory!");
547553 return false;
548554 }
549555
556+ tmpPathU[0] = 0;
557+ filenameU[0] = 0;
558+
550559 #ifdef _WIN32
551− MultiByteToWideChar(CP_UTF8, 0, argv[1], -1, filenameU, filenameLen);
560+ MultiByteToWideChar(CP_UTF8, 0, argv[1], -1, filenameU, filenameLen+1);
552561 #else
553562 strcpy(filenameU, argv[1]);
554563 #endif
@@ -562,9 +571,11 @@ bool handleModuleLoadFromArg(int argc, char **argv) · 7 unmodified lines
562571 const int32_t filesize = getFileSize(filenameU);
563572 if (filesize == -1 || filesize >= 512L*1024*1024) // 1) >=2GB 2) >=512MB
564573 {
565− okBox(0, "System message", "Error: The module is too big to be loaded!");
566574 free(filenameU);
567575 UNICHAR_CHDIR(tmpPathU); // set old path back
576+ free(tmpPathU);
577+
578+ okBox(0, "System message", "Error: The module is too big to be loaded!");
568579 return false;
569580 }
570581
@@ -572,6 +583,8 @@ bool handleModuleLoadFromArg(int argc, char **argv) · 1 unmodified line
572583
573584 free(filenameU);
574585 UNICHAR_CHDIR(tmpPathU); // set old path back
586+ free(tmpPathU);
587+
575588 return result;
576589 }
577590
@@ -642,15 +655,17 @@ void loadDroppedFile(char *fullPathUTF8, bool songModifiedCheck) · 64 unmodified lines
642655 if (fullPathLen == 0)
643656 return;
644657
645− UNICHAR *fullPathU = (UNICHAR *)calloc(fullPathLen + 2, sizeof (UNICHAR));
658+ UNICHAR *fullPathU = (UNICHAR *)malloc((fullPathLen + 1) * sizeof (UNICHAR));
646659 if (fullPathU == NULL)
647660 {
648661 okBox(0, "System message", "Not enough memory!");
649662 return;
650663 }
651664
665+ fullPathU[0] = 0;
666+
652667 #ifdef _WIN32
653− MultiByteToWideChar(CP_UTF8, 0, fullPathUTF8, -1, fullPathU, fullPathLen);
668+ MultiByteToWideChar(CP_UTF8, 0, fullPathUTF8, -1, fullPathU, fullPathLen+1);
654669 #else
655670 strcpy(fullPathU, fullPathUTF8);
656671 #endif
src/ft2_mouse.c+5−2
@@ -301,7 +301,7 @@ static void changeCursorIfOverTextBoxes(void) · 300 unmodified lines
301301 textBox_t *t = textBoxes;
302302 for (i = 0; i < NUM_TEXTBOXES; i++, t++)
303303 {
304− if (ui.sysReqShown && i > 0)
304+ if (ui.sysReqShown && i != 0) // Sys. Req can only have one (special) text box
305305 continue;
306306
307307 if (!t->visible)
@@ -313,7 +313,10 @@ static void changeCursorIfOverTextBoxes(void) · 5 unmodified lines
313313 if (my >= t->y && my < t->y+t->h && mx >= t->x && mx < t->x+t->w)
314314 {
315315 mouse.mouseOverTextBox = true;
316− setTextEditMouse();
316+
317+ if (mouseShape != MOUSE_IDLE_TEXT_EDIT)
318+ setTextEditMouse();
319+
317320 return;
318321 }
319322 }
src/ft2_structs.h+2−3
@@ -11,9 +11,8 @@ typedef struct cpu_t · 10 unmodified lines
1111
1212 typedef struct editor_t
1313 {
14− UNICHAR binaryPathU[PATH_MAX + 2];
15− UNICHAR *tmpFilenameU, *tmpInstrFilenameU; // used by saving/loading threads
16− UNICHAR *configFileLocation, *audioDevConfigFileLocation, *midiConfigFileLocation;
14+ UNICHAR *binaryPathU, *tmpFilenameU, *tmpInstrFilenameU; // used by saving/loading threads
15+ UNICHAR *configFileLocationU, *audioDevConfigFileLocationU, *midiConfigFileLocationU;
1716
1817 volatile bool mainLoopOngoing;
1918 volatile bool busy, scopeThreadMutex, programRunning, wavIsRendering, wavReachedEndFlag;
src/ft2_sysreqs.c+5−2
@@ -299,8 +299,11 @@ int16_t okBox(int16_t typ, const char *headline, const char *text) · 298 unmodified lines
299299 {
300300 if (inputEvent.key.keysym.sym == SDLK_ESCAPE)
301301 {
302− returnVal = 0;
303− ui.sysReqShown = false;
302+ if (!inputEvent.key.repeat) // don't let previously held-down ESC immediately close the box
303+ {
304+ returnVal = 0;
305+ ui.sysReqShown = false;
306+ }
304307 }
305308 else if (inputEvent.key.keysym.sym == SDLK_RETURN)
306309 {
src/ft2_textboxes.c+1−1
@@ -52,7 +52,7 @@ textBox_t textBoxes[NUM_TEXTBOXES] = · 51 unmodified lines
5252
5353 // ------ DISK OP. TEXTBOXES ------
5454 // x, y, w, h, tx,ty, maxc, rmb, cmc
55− { 31, 158, 134, 12, 2, 1, PATH_MAX-1, false, true },
55+ { 31, 158, 134, 12, 2, 1, PATH_MAX, false, true },
5656
5757 // ------ CONFIG TEXTBOXES ------
5858 // x, y, w, h, tx,ty, maxc, rmb, cmc
src/ft2_unicode.c+11−8
@@ -57,15 +57,14 @@ char *cp437ToUtf8(char *src) · 56 unmodified lines
5757 return NULL;
5858 }
5959
60− char *x = (char *)malloc((reqSize + 2) * sizeof (char));
60+ char *x = (char *)malloc((reqSize + 1) * sizeof (char));
6161 if (x == NULL)
6262 {
6363 free(w);
6464 return NULL;
6565 }
6666
67− x[reqSize+0] = '\0';
68− x[reqSize+1] = '\0';
67+ x[reqSize] = '\0';
6968
7069 retVal = WideCharToMultiByte(CP_UTF8, 0, w, srcLen, x, reqSize, 0, 0);
7170 free(w);
@@ -148,7 +147,7 @@ char *utf8ToCp437(char *src, bool removeIllegalChars) · 76 unmodified lines
148147 return NULL;
149148 }
150149
151− char *x = (char *)calloc(reqSize + 1, sizeof (char));
150+ char *x = (char *)malloc((reqSize + 1) * sizeof (char));
152151 if (x == NULL)
153152 {
154153 free(w);
@@ -216,7 +215,7 @@ char *unicharToCp437(UNICHAR *src, bool removeIllegalChars) · 61 unmodified lines
216215 {
217216 const int8_t ch = (const int8_t)x[i];
218217 if (ch < 32 && ch != 0 && ch != -124 && ch != -108 &&
219− ch != -122 && ch != -114 && ch != -103 && ch != -113)
218+ ch != -122 && ch != -114 && ch != -103 && ch != -113)
220219 {
221220 x[i] = ' '; // character not allowed, turn it into space
222221 }
@@ -244,7 +243,7 @@ char *cp437ToUtf8(char *src) · 21 unmodified lines
244243
245244 size_t outLen = srcLen * 2; // should be sufficient
246245
247− char *outBuf = (char *)calloc(outLen + 2, sizeof (char));
246+ char *outBuf = (char *)malloc((outLen + 1) * sizeof (char));
248247 if (outBuf == NULL)
249248 return NULL;
250249
@@ -266,6 +265,8 @@ char *cp437ToUtf8(char *src) · 15 unmodified lines
266265 return NULL;
267266 }
268267
268+ outBuf[outLen] = '\0';
269+
269270 return outBuf;
270271 }
271272
@@ -290,7 +291,7 @@ char *utf8ToCp437(char *src, bool removeIllegalChars) · 18 unmodified lines
290291
291292 size_t outLen = srcLen * 2; // should be sufficient
292293
293− char *outBuf = (char *)calloc(outLen + 1, sizeof (char));
294+ char *outBuf = (char *)malloc((outLen + 1) * sizeof (char));
294295 if (outBuf == NULL)
295296 return NULL;
296297
@@ -312,6 +313,8 @@ char *utf8ToCp437(char *src, bool removeIllegalChars) · 15 unmodified lines
312313 return NULL;
313314 }
314315
316+ outBuf[outLen] = '\0';
317+
315318 if (removeIllegalChars)
316319 {
317320 // remove illegal characters (only allow certain nordic ones)
@@ -319,7 +322,7 @@ char *utf8ToCp437(char *src, bool removeIllegalChars) · 1 unmodified line
319322 {
320323 const int8_t ch = (const int8_t)outBuf[i];
321324 if (ch < 32 && ch != 0 && ch != -124 && ch != -108 &&
322− ch != -122 && ch != -114 && ch != -103 && ch != -113)
325+ ch != -122 && ch != -114 && ch != -103 && ch != -113)
323326 {
324327 outBuf[i] = ' '; // character not allowed, turn it into space
325328 }
src/ft2_video.c+7−3
@@ -46,7 +46,7 @@ static const uint8_t textCursorData[12] = · 45 unmodified lines
4646 video_t video; // globalized
4747
4848 static bool songIsModified;
49−static char wndTitle[128 + PATH_MAX];
49+static char wndTitle[256];
5050 static uint64_t timeNext64, timeNext64Frac;
5151 static sprite_t sprites[SPRITE_NUM];
5252
@@ -845,10 +845,14 @@ void updateWindowTitle(bool forceUpdate) · 792 unmodified lines
845845 char *songTitle = getCurrSongFilename();
846846 if (songTitle != NULL)
847847 {
848+ char songTitleTrunc[128];
849+ strncpy(songTitleTrunc, songTitle, sizeof (songTitleTrunc)-1);
850+ songTitleTrunc[sizeof (songTitleTrunc)-1] = '\0';
851+
848852 if (song.isModified)
849− sprintf(wndTitle, "Fasttracker II clone v%s - \"%s\" (unsaved)", PROG_VER_STR, songTitle);
853+ sprintf(wndTitle, "Fasttracker II clone v%s - \"%s\" (unsaved)", PROG_VER_STR, songTitleTrunc);
850854 else
851− sprintf(wndTitle, "Fasttracker II clone v%s - \"%s\"", PROG_VER_STR, songTitle);
855+ sprintf(wndTitle, "Fasttracker II clone v%s - \"%s\"", PROG_VER_STR, songTitleTrunc);
852856 }
853857 else
854858 {
src/helpdata/FT2.HLP+0−4
@@ -923,10 +923,6 @@ END · 922 unmodified lines
923923 and you need to press a key or click the mouse to abort the render when you want
924924 it to.
925925 >@X010
926−>@C001Mouse / keyboard:
927−>
928−>@C002- Linux: The mouse cursor graphics can be glitchy at times...
929−>@X010
930926 >@C001Video:
931927 >@C002
932928 >@X010- Fullscreen mode can be unbearably slow on a Raspberry Pi (even on RPi 4)
src/helpdata/ft2_help_data.h+34−42
@@ -3,9 +3,9 @@ · 2 unmodified lines
33
44 #include <stdint.h>
55
6−#define HELP_DATA_LEN 27486
6+#define HELP_DATA_LEN 27385
77
8−const uint8_t helpData[27486] =
8+const uint8_t helpData[27385] =
99 {
1010 0x4C,0x3B,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
1111 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
@@ -2258,46 +2258,38 @@ const uint8_t helpData[27486] = · 2246 unmodified lines
22582258 0x74,0x6F,0x20,0x61,0x62,0x6F,0x72,0x74,0x20,0x74,0x68,0x65,
22592259 0x20,0x72,0x65,0x6E,0x64,0x65,0x72,0x20,0x77,0x68,0x65,0x6E,
22602260 0x20,0x79,0x6F,0x75,0x20,0x77,0x61,0x6E,0x74,0x06,0x69,0x74,
2261− 0x20,0x74,0x6F,0x2E,0x06,0x3E,0x40,0x58,0x30,0x31,0x30,0x17,
2262− 0x3E,0x40,0x43,0x30,0x30,0x31,0x4D,0x6F,0x75,0x73,0x65,0x20,
2263− 0x2F,0x20,0x6B,0x65,0x79,0x62,0x6F,0x61,0x72,0x64,0x3A,0x01,
2264− 0x3E,0x43,0x3E,0x40,0x43,0x30,0x30,0x32,0x2D,0x20,0x4C,0x69,
2265− 0x6E,0x75,0x78,0x3A,0x20,0x54,0x68,0x65,0x20,0x6D,0x6F,0x75,
2266− 0x73,0x65,0x20,0x63,0x75,0x72,0x73,0x6F,0x72,0x20,0x67,0x72,
2267− 0x61,0x70,0x68,0x69,0x63,0x73,0x20,0x63,0x61,0x6E,0x20,0x62,
2268− 0x65,0x20,0x67,0x6C,0x69,0x74,0x63,0x68,0x79,0x20,0x61,0x74,
2269− 0x20,0x74,0x69,0x6D,0x65,0x73,0x2E,0x2E,0x2E,0x06,0x3E,0x40,
2270− 0x58,0x30,0x31,0x30,0x0C,0x3E,0x40,0x43,0x30,0x30,0x31,0x56,
2271− 0x69,0x64,0x65,0x6F,0x3A,0x06,0x3E,0x40,0x43,0x30,0x30,0x32,
2272− 0x50,0x3E,0x40,0x58,0x30,0x31,0x30,0x2D,0x20,0x46,0x75,0x6C,
2273− 0x6C,0x73,0x63,0x72,0x65,0x65,0x6E,0x20,0x6D,0x6F,0x64,0x65,
2274− 0x20,0x63,0x61,0x6E,0x20,0x62,0x65,0x20,0x75,0x6E,0x62,0x65,
2275− 0x61,0x72,0x61,0x62,0x6C,0x79,0x20,0x73,0x6C,0x6F,0x77,0x20,
2276− 0x6F,0x6E,0x20,0x61,0x20,0x52,0x61,0x73,0x70,0x62,0x65,0x72,
2277− 0x72,0x79,0x20,0x50,0x69,0x20,0x28,0x65,0x76,0x65,0x6E,0x20,
2278− 0x6F,0x6E,0x20,0x52,0x50,0x69,0x20,0x34,0x29,0x01,0x3E,0x52,
2279− 0x3E,0x40,0x58,0x30,0x31,0x30,0x2D,0x20,0x4E,0x6F,0x74,0x20,
2280− 0x61,0x20,0x62,0x75,0x67,0x2C,0x20,0x62,0x75,0x74,0x20,0x69,
2281− 0x66,0x20,0x79,0x6F,0x75,0x72,0x20,0x6D,0x6F,0x6E,0x69,0x74,
2282− 0x6F,0x72,0x27,0x73,0x20,0x72,0x65,0x66,0x72,0x65,0x73,0x68,
2283− 0x20,0x72,0x61,0x74,0x65,0x20,0x69,0x73,0x20,0x6E,0x6F,0x74,
2284− 0x20,0x73,0x65,0x74,0x20,0x74,0x6F,0x20,0x36,0x30,0x48,0x7A,
2285− 0x20,0x28,0x6F,0x72,0x20,0x35,0x39,0x48,0x7A,0x29,0x4F,0x3E,
2286− 0x40,0x58,0x30,0x32,0x31,0x79,0x6F,0x75,0x20,0x6D,0x61,0x79,
2287− 0x20,0x65,0x78,0x70,0x65,0x72,0x69,0x65,0x6E,0x63,0x65,0x20,
2288− 0x76,0x69,0x73,0x75,0x61,0x6C,0x20,0x73,0x74,0x75,0x74,0x74,
2289− 0x65,0x72,0x69,0x6E,0x67,0x20,0x62,0x65,0x63,0x61,0x75,0x73,
2290− 0x65,0x20,0x56,0x53,0x79,0x6E,0x63,0x20,0x77,0x69,0x6C,0x6C,
2291− 0x20,0x6E,0x6F,0x74,0x20,0x62,0x65,0x20,0x75,0x73,0x65,0x64,
2292− 0x20,0x74,0x68,0x65,0x6E,0x2E,0x51,0x49,0x20,0x68,0x69,0x67,
2293− 0x68,0x6C,0x79,0x20,0x72,0x65,0x63,0x6F,0x6D,0x6D,0x65,0x6E,
2294− 0x64,0x20,0x72,0x75,0x6E,0x6E,0x69,0x6E,0x67,0x20,0x79,0x6F,
2295− 0x75,0x72,0x20,0x6D,0x6F,0x6E,0x69,0x74,0x6F,0x72,0x20,0x61,
2296− 0x74,0x20,0x36,0x30,0x48,0x7A,0x20,0x69,0x66,0x20,0x79,0x6F,
2297− 0x75,0x27,0x72,0x65,0x20,0x61,0x20,0x68,0x61,0x72,0x64,0x63,
2298− 0x6F,0x72,0x65,0x20,0x75,0x73,0x65,0x72,0x20,0x6F,0x66,0x20,
2299− 0x74,0x68,0x69,0x73,0x08,0x70,0x72,0x6F,0x67,0x72,0x61,0x6D,
2300− 0x2E,0x00,0x03,0x45,0x4E,0x44
2261+ 0x20,0x74,0x6F,0x2E,0x06,0x3E,0x40,0x58,0x30,0x31,0x30,0x0C,
2262+ 0x3E,0x40,0x43,0x30,0x30,0x31,0x56,0x69,0x64,0x65,0x6F,0x3A,
2263+ 0x06,0x3E,0x40,0x43,0x30,0x30,0x32,0x50,0x3E,0x40,0x58,0x30,
2264+ 0x31,0x30,0x2D,0x20,0x46,0x75,0x6C,0x6C,0x73,0x63,0x72,0x65,
2265+ 0x65,0x6E,0x20,0x6D,0x6F,0x64,0x65,0x20,0x63,0x61,0x6E,0x20,
2266+ 0x62,0x65,0x20,0x75,0x6E,0x62,0x65,0x61,0x72,0x61,0x62,0x6C,
2267+ 0x79,0x20,0x73,0x6C,0x6F,0x77,0x20,0x6F,0x6E,0x20,0x61,0x20,
2268+ 0x52,0x61,0x73,0x70,0x62,0x65,0x72,0x72,0x79,0x20,0x50,0x69,
2269+ 0x20,0x28,0x65,0x76,0x65,0x6E,0x20,0x6F,0x6E,0x20,0x52,0x50,
2270+ 0x69,0x20,0x34,0x29,0x01,0x3E,0x52,0x3E,0x40,0x58,0x30,0x31,
2271+ 0x30,0x2D,0x20,0x4E,0x6F,0x74,0x20,0x61,0x20,0x62,0x75,0x67,
2272+ 0x2C,0x20,0x62,0x75,0x74,0x20,0x69,0x66,0x20,0x79,0x6F,0x75,
2273+ 0x72,0x20,0x6D,0x6F,0x6E,0x69,0x74,0x6F,0x72,0x27,0x73,0x20,
2274+ 0x72,0x65,0x66,0x72,0x65,0x73,0x68,0x20,0x72,0x61,0x74,0x65,
2275+ 0x20,0x69,0x73,0x20,0x6E,0x6F,0x74,0x20,0x73,0x65,0x74,0x20,
2276+ 0x74,0x6F,0x20,0x36,0x30,0x48,0x7A,0x20,0x28,0x6F,0x72,0x20,
2277+ 0x35,0x39,0x48,0x7A,0x29,0x4F,0x3E,0x40,0x58,0x30,0x32,0x31,
2278+ 0x79,0x6F,0x75,0x20,0x6D,0x61,0x79,0x20,0x65,0x78,0x70,0x65,
2279+ 0x72,0x69,0x65,0x6E,0x63,0x65,0x20,0x76,0x69,0x73,0x75,0x61,
2280+ 0x6C,0x20,0x73,0x74,0x75,0x74,0x74,0x65,0x72,0x69,0x6E,0x67,
2281+ 0x20,0x62,0x65,0x63,0x61,0x75,0x73,0x65,0x20,0x56,0x53,0x79,
2282+ 0x6E,0x63,0x20,0x77,0x69,0x6C,0x6C,0x20,0x6E,0x6F,0x74,0x20,
2283+ 0x62,0x65,0x20,0x75,0x73,0x65,0x64,0x20,0x74,0x68,0x65,0x6E,
2284+ 0x2E,0x51,0x49,0x20,0x68,0x69,0x67,0x68,0x6C,0x79,0x20,0x72,
2285+ 0x65,0x63,0x6F,0x6D,0x6D,0x65,0x6E,0x64,0x20,0x72,0x75,0x6E,
2286+ 0x6E,0x69,0x6E,0x67,0x20,0x79,0x6F,0x75,0x72,0x20,0x6D,0x6F,
2287+ 0x6E,0x69,0x74,0x6F,0x72,0x20,0x61,0x74,0x20,0x36,0x30,0x48,
2288+ 0x7A,0x20,0x69,0x66,0x20,0x79,0x6F,0x75,0x27,0x72,0x65,0x20,
2289+ 0x61,0x20,0x68,0x61,0x72,0x64,0x63,0x6F,0x72,0x65,0x20,0x75,
2290+ 0x73,0x65,0x72,0x20,0x6F,0x66,0x20,0x74,0x68,0x69,0x73,0x08,
2291+ 0x70,0x72,0x6F,0x67,0x72,0x61,0x6D,0x2E,0x00,0x03,0x45,0x4E,
2292+ 0x44
23012293 };
23022294
23032295 #endif

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t