shithub: ft²

Download patch

ref: 77e70eb42d0b3b7430fba684c9f024fdcc0ff9ce
parent: 385b3d29571b93a2054d378ebc41739064b08221
parent: fbdd310a2c207e0c239c1a5d69c313336e61e77b
author: qwx <qwx@sciops.net>
date: Sat Sep 16 00:17:37 EDT 2023

sync with ftrv

--- a/HOW-TO-COMPILE.txt
+++ b/HOW-TO-COMPILE.txt
@@ -1,15 +1,7 @@
 ---- Guide on how to compile the FT2 clone for Windows/macOS/Linux ---
 
-LINUX NOTE: This code is NOT big-endian compatible! And converting it would take
-            a ton of time, as I fread()/fwrite() directly to/from structs and
-            stuff (like original FT2). The structs are also packed, with
-            unaligned 16-bit/32-bit entries, so the clone might fail on certain
-            CPUs (except x86/x86_64, ARM11 and never). The clone might also
-            behave slightly wrong if bitshift-right on signed numbers is
-            compiled into using logical shift (LSR/SHR) instead of arithmetic
-            shift (ASR/SAR). Most CPUs have ASR/SAR instructions.
-              
-      
+LINUX NOTE: This code is NOT big-endian compatible!
+
 Compiled Windows/macOS binaries are always available at 16-bits.org/ft2.php
 
 
--- a/release/macos/ft2-clone-macos.app/Contents/Frameworks/SDL2.framework/Versions/A/Headers/SDL_atomic.h
+++ b/release/macos/ft2-clone-macos.app/Contents/Frameworks/SDL2.framework/Versions/A/Headers/SDL_atomic.h
@@ -249,9 +249,8 @@
 #elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_ARM64))
     #define SDL_CPUPauseInstruction() __yield()
 #elif defined(__WATCOMC__) && defined(__386__)
-    /* watcom assembler rejects PAUSE if CPU < i686, and it refuses REP NOP as an invalid combination. Hardcode the bytes.  */
     extern __inline void SDL_CPUPauseInstruction(void);
-    #pragma aux SDL_CPUPauseInstruction = "db 0f3h,90h"
+    #pragma aux SDL_CPUPauseInstruction = ".686p" ".xmm2" "pause"
 #else
     #define SDL_CPUPauseInstruction()
 #endif
--- a/release/macos/ft2-clone-macos.app/Contents/Frameworks/SDL2.framework/Versions/A/Headers/SDL_audio.h
+++ b/release/macos/ft2-clone-macos.app/Contents/Frameworks/SDL2.framework/Versions/A/Headers/SDL_audio.h
@@ -169,13 +169,13 @@
  *  The calculated values in this structure are calculated by SDL_OpenAudio().
  *
  *  For multi-channel audio, the default SDL channel mapping is:
- *  2:  FL FR                       (stereo)
- *  3:  FL FR LFE                   (2.1 surround)
- *  4:  FL FR BL BR                 (quad)
- *  5:  FL FR LFE BL BR             (4.1 surround)
- *  6:  FL FR FC LFE SL SR          (5.1 surround - last two can also be BL BR)
- *  7:  FL FR FC LFE BC SL SR       (6.1 surround)
- *  8:  FL FR FC LFE BL BR SL SR    (7.1 surround)
+ *  2:  FL  FR                          (stereo)
+ *  3:  FL  FR LFE                      (2.1 surround)
+ *  4:  FL  FR  BL  BR                  (quad)
+ *  5:  FL  FR LFE  BL  BR              (4.1 surround)
+ *  6:  FL  FR  FC LFE  SL  SR          (5.1 surround - last two can also be BL BR)
+ *  7:  FL  FR  FC LFE  BC  SL  SR      (6.1 surround)
+ *  8:  FL  FR  FC LFE  BL  BR  SL  SR  (7.1 surround)
  */
 typedef struct SDL_AudioSpec
 {
--- a/release/macos/ft2-clone-macos.app/Contents/Frameworks/SDL2.framework/Versions/A/Headers/SDL_blendmode.h
+++ b/release/macos/ft2-clone-macos.app/Contents/Frameworks/SDL2.framework/Versions/A/Headers/SDL_blendmode.h
@@ -52,7 +52,7 @@
                                               dstA = dstA */
     SDL_BLENDMODE_MUL = 0x00000008,      /**< color multiply
                                               dstRGB = (srcRGB * dstRGB) + (dstRGB * (1-srcA))
-                                              dstA = (srcA * dstA) + (dstA * (1-srcA)) */
+                                              dstA = dstA */
     SDL_BLENDMODE_INVALID = 0x7FFFFFFF
 
     /* Additional custom blend modes can be returned by SDL_ComposeCustomBlendMode() */
--- a/release/macos/ft2-clone-macos.app/Contents/Frameworks/SDL2.framework/Versions/A/Headers/SDL_endian.h
+++ b/release/macos/ft2-clone-macos.app/Contents/Frameworks/SDL2.framework/Versions/A/Headers/SDL_endian.h
@@ -140,7 +140,7 @@
 
 #if HAS_BUILTIN_BSWAP16
 #define SDL_Swap16(x) __builtin_bswap16(x)
-#elif defined(_MSC_VER) && (_MSC_VER >= 1400)
+#elif (defined(_MSC_VER) && (_MSC_VER >= 1400)) && !defined(__ICL)
 #pragma intrinsic(_byteswap_ushort)
 #define SDL_Swap16(x) _byteswap_ushort(x)
 #elif defined(__i386__) && !HAS_BROKEN_BSWAP
@@ -189,7 +189,7 @@
 
 #if HAS_BUILTIN_BSWAP32
 #define SDL_Swap32(x) __builtin_bswap32(x)
-#elif defined(_MSC_VER) && (_MSC_VER >= 1400)
+#elif (defined(_MSC_VER) && (_MSC_VER >= 1400)) && !defined(__ICL)
 #pragma intrinsic(_byteswap_ulong)
 #define SDL_Swap32(x) _byteswap_ulong(x)
 #elif defined(__i386__) && !HAS_BROKEN_BSWAP
@@ -241,7 +241,7 @@
 
 #if HAS_BUILTIN_BSWAP64
 #define SDL_Swap64(x) __builtin_bswap64(x)
-#elif defined(_MSC_VER) && (_MSC_VER >= 1400)
+#elif (defined(_MSC_VER) && (_MSC_VER >= 1400)) && !defined(__ICL)
 #pragma intrinsic(_byteswap_uint64)
 #define SDL_Swap64(x) _byteswap_uint64(x)
 #elif defined(__i386__) && !HAS_BROKEN_BSWAP
--- a/release/macos/ft2-clone-macos.app/Contents/Frameworks/SDL2.framework/Versions/A/Headers/SDL_gamecontroller.h
+++ b/release/macos/ft2-clone-macos.app/Contents/Frameworks/SDL2.framework/Versions/A/Headers/SDL_gamecontroller.h
@@ -724,10 +724,10 @@
     SDL_CONTROLLER_BUTTON_DPAD_LEFT,
     SDL_CONTROLLER_BUTTON_DPAD_RIGHT,
     SDL_CONTROLLER_BUTTON_MISC1,    /* Xbox Series X share button, PS5 microphone button, Nintendo Switch Pro capture button, Amazon Luna microphone button */
-    SDL_CONTROLLER_BUTTON_PADDLE1,  /* Xbox Elite paddle P1 */
-    SDL_CONTROLLER_BUTTON_PADDLE2,  /* Xbox Elite paddle P3 */
-    SDL_CONTROLLER_BUTTON_PADDLE3,  /* Xbox Elite paddle P2 */
-    SDL_CONTROLLER_BUTTON_PADDLE4,  /* Xbox Elite paddle P4 */
+    SDL_CONTROLLER_BUTTON_PADDLE1,  /* Xbox Elite paddle P1 (upper left, facing the back) */
+    SDL_CONTROLLER_BUTTON_PADDLE2,  /* Xbox Elite paddle P3 (upper right, facing the back) */
+    SDL_CONTROLLER_BUTTON_PADDLE3,  /* Xbox Elite paddle P2 (lower left, facing the back) */
+    SDL_CONTROLLER_BUTTON_PADDLE4,  /* Xbox Elite paddle P4 (lower right, facing the back) */
     SDL_CONTROLLER_BUTTON_TOUCHPAD, /* PS4/PS5 touchpad button */
     SDL_CONTROLLER_BUTTON_MAX
 } SDL_GameControllerButton;
--- a/release/macos/ft2-clone-macos.app/Contents/Frameworks/SDL2.framework/Versions/A/Headers/SDL_hints.h
+++ b/release/macos/ft2-clone-macos.app/Contents/Frameworks/SDL2.framework/Versions/A/Headers/SDL_hints.h
@@ -92,7 +92,7 @@
  * By default this hint is not set and the APK expansion files are not searched.
  */
 #define SDL_HINT_ANDROID_APK_EXPANSION_MAIN_FILE_VERSION "SDL_ANDROID_APK_EXPANSION_MAIN_FILE_VERSION"
- 
+
 /**
  * \brief Android APK expansion patch file version. Should be a string number like "1", "2" etc.
  *
@@ -132,13 +132,13 @@
  * \brief A variable to control whether we trap the Android back button to handle it manually.
  *        This is necessary for the right mouse button to work on some Android devices, or
  *        to be able to trap the back button for use in your code reliably.  If set to true,
- *        the back button will show up as an SDL_KEYDOWN / SDL_KEYUP pair with a keycode of 
+ *        the back button will show up as an SDL_KEYDOWN / SDL_KEYUP pair with a keycode of
  *        SDL_SCANCODE_AC_BACK.
  *
  * The variable can be set to the following values:
  *   "0"       - Back button will be handled as usual for system. (default)
  *   "1"       - Back button will be trapped, allowing you to handle the key press
- *               manually.  (This will also let right mouse click work on systems 
+ *               manually.  (This will also let right mouse click work on systems
  *               where the right mouse button functions as back.)
  *
  * The value of this hint is used at runtime, so it can be changed at any time.
@@ -147,7 +147,7 @@
 
 /**
  *  \brief Specify an application name.
- * 
+ *
  * This hint lets you specify the application name sent to the OS when
  * required. For example, this will often appear in volume control applets for
  * audio streams, and in lists of applications which are inhibiting the
@@ -378,6 +378,17 @@
 #define SDL_HINT_EMSCRIPTEN_KEYBOARD_ELEMENT   "SDL_EMSCRIPTEN_KEYBOARD_ELEMENT"
 
 /**
+ *  \brief  A variable that controls whether the on-screen keyboard should be shown when text input is active
+ *
+ *  The variable can be set to the following values:
+ *    "0"       - Do not show the on-screen keyboard
+ *    "1"       - Show the on-screen keyboard
+ *
+ *  The default value is "1". This hint must be set before text input is activated.
+ */
+#define SDL_HINT_ENABLE_SCREEN_KEYBOARD "SDL_ENABLE_SCREEN_KEYBOARD"
+
+/**
  *  \brief  A variable that controls whether Steam Controllers should be exposed using the SDL joystick and game controller APIs
  *
  *  The variable can be set to the following values:
@@ -507,7 +518,7 @@
 
 /**
  *  \brief  If set, game controller face buttons report their values according to their labels instead of their positional layout.
- * 
+ *
  *  For example, on Nintendo Switch controllers, normally you'd get:
  *
  *      (Y)
@@ -569,9 +580,9 @@
  *
  * The variable can be set to the following values:
  *   "0"       - SDL_TEXTEDITING events are sent, and it is the application's
- *               responsibility to render the text from these events and 
+ *               responsibility to render the text from these events and
  *               differentiate it somehow from committed text. (default)
- *   "1"       - If supported by the IME then SDL_TEXTEDITING events are not sent, 
+ *   "1"       - If supported by the IME then SDL_TEXTEDITING events are not sent,
  *               and text that is being composed will be rendered in its own UI.
  */
 #define SDL_HINT_IME_INTERNAL_EDITING "SDL_IME_INTERNAL_EDITING"
@@ -1310,6 +1321,8 @@
  *
  *  This variable can be one of the following values:
  *    "primary" (default), "portrait", "landscape", "inverted-portrait", "inverted-landscape"
+ *
+ *  Since SDL 2.0.22 this variable accepts a comma-separated list of values above.
  */
 #define SDL_HINT_QTWAYLAND_CONTENT_ORIENTATION "SDL_QTWAYLAND_CONTENT_ORIENTATION"
 
@@ -1495,7 +1508,7 @@
  * disabled. You should use a string that describes what your program is doing
  * (and, therefore, why the screensaver is disabled).  For example, "Playing a
  * game" or "Watching a video".
- * 
+ *
  * Setting this to "" or leaving it unset will have SDL use a reasonable
  * default: "Playing a game" or something similar.
  *
@@ -1509,13 +1522,13 @@
  *  On some platforms, like Linux, a realtime priority thread may be subject to restrictions
  *  that require special handling by the application. This hint exists to let SDL know that
  *  the app is prepared to handle said restrictions.
- * 
+ *
  *  On Linux, SDL will apply the following configuration to any thread that becomes realtime:
  *   * The SCHED_RESET_ON_FORK bit will be set on the scheduling policy,
  *   * An RLIMIT_RTTIME budget will be configured to the rtkit specified limit.
  *     * Exceeding this limit will result in the kernel sending SIGKILL to the app,
  *     * Refer to the man pages for more information.
- * 
+ *
  *  This variable can be set to the following values:
  *    "0"       - default platform specific behaviour
  *    "1"       - Force SDL_THREAD_PRIORITY_TIME_CRITICAL to a realtime scheduling policy
@@ -1603,7 +1616,7 @@
 #define SDL_HINT_TV_REMOTE_AS_JOYSTICK "SDL_TV_REMOTE_AS_JOYSTICK"
 
 /**
- *  \brief  A variable controlling whether the screensaver is enabled. 
+ *  \brief  A variable controlling whether the screensaver is enabled.
  *
  *  This variable can be set to the following values:
  *    "0"       - Disable screensaver
@@ -1616,7 +1629,7 @@
 /**
  * \brief Tell the video driver that we only want a double buffer.
  *
- * By default, most lowlevel 2D APIs will use a triple buffer scheme that 
+ * By default, most lowlevel 2D APIs will use a triple buffer scheme that
  * wastes no CPU time on waiting for vsync after issuing a flip, but
  * introduces a frame of latency. On the other hand, using a double buffer
  * scheme instead is recommended for cases where low latency is an important
@@ -1747,9 +1760,9 @@
 
 /**
 *  \brief  A variable that is the address of another SDL_Window* (as a hex string formatted with "%p").
-*  
+*
 *  If this hint is set before SDL_CreateWindowFrom() and the SDL_Window* it is set to has
-*  SDL_WINDOW_OPENGL set (and running on WGL only, currently), then two things will occur on the newly 
+*  SDL_WINDOW_OPENGL set (and running on WGL only, currently), then two things will occur on the newly
 *  created SDL_Window:
 *
 *  1. Its pixel format will be set to the same pixel format as this SDL_Window.  This is
@@ -1815,13 +1828,13 @@
 
 /**
  * \brief A variable controlling whether the X11 _NET_WM_BYPASS_COMPOSITOR hint should be used.
- * 
+ *
  * This variable can be set to the following values:
  * "0" - Disable _NET_WM_BYPASS_COMPOSITOR
  * "1" - Enable _NET_WM_BYPASS_COMPOSITOR
- * 
+ *
  * By default SDL will use _NET_WM_BYPASS_COMPOSITOR
- * 
+ *
  */
 #define SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR "SDL_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR"
 
@@ -1955,9 +1968,31 @@
 #define SDL_HINT_WINDOWS_DISABLE_THREAD_NAMING "SDL_WINDOWS_DISABLE_THREAD_NAMING"
 
 /**
- *  \brief  A variable controlling whether the windows message loop is processed by SDL 
+ *  \brief Controls whether menus can be opened with their keyboard shortcut (Alt+mnemonic).
  *
+ *  If the mnemonics are enabled, then menus can be opened by pressing the Alt
+ *  key and the corresponding mnemonic (for example, Alt+F opens the File menu).
+ *  However, in case an invalid mnemonic is pressed, Windows makes an audible
+ *  beep to convey that nothing happened. This is true even if the window has
+ *  no menu at all!
+ *
+ *  Because most SDL applications don't have menus, and some want to use the Alt
+ *  key for other purposes, SDL disables mnemonics (and the beeping) by default.
+ *
+ *  Note: This also affects keyboard events: with mnemonics enabled, when a
+ *  menu is opened from the keyboard, you will not receive a KEYUP event for
+ *  the mnemonic key, and *might* not receive one for Alt.
+ *
  *  This variable can be set to the following values:
+ *    "0"       - Alt+mnemonic does nothing, no beeping. (default)
+ *    "1"       - Alt+mnemonic opens menus, invalid mnemonics produce a beep.
+ */
+#define SDL_HINT_WINDOWS_ENABLE_MENU_MNEMONICS "SDL_WINDOWS_ENABLE_MENU_MNEMONICS"
+
+/**
+ *  \brief  A variable controlling whether the windows message loop is processed by SDL
+ *
+ *  This variable can be set to the following values:
  *    "0"       - The window message loop is not run
  *    "1"       - The window message loop is processed in SDL_PumpEvents()
  *
@@ -1996,7 +2031,7 @@
 #define SDL_HINT_WINDOWS_FORCE_SEMAPHORE_KERNEL "SDL_WINDOWS_FORCE_SEMAPHORE_KERNEL"
 
 /**
- * \brief A variable to specify custom icon resource id from RC file on Windows platform 
+ * \brief A variable to specify custom icon resource id from RC file on Windows platform
  */
 #define SDL_HINT_WINDOWS_INTRESOURCE_ICON       "SDL_WINDOWS_INTRESOURCE_ICON"
 #define SDL_HINT_WINDOWS_INTRESOURCE_ICON_SMALL "SDL_WINDOWS_INTRESOURCE_ICON_SMALL"
@@ -2035,16 +2070,16 @@
  *
  *  This hint must be set before initializing the video subsystem.
  *
- *  The main purpose of declaring DPI awareness is to disable OS bitmap scaling of SDL windows on monitors with 
+ *  The main purpose of declaring DPI awareness is to disable OS bitmap scaling of SDL windows on monitors with
  *  a DPI scale factor.
- * 
+ *
  *  This hint is equivalent to requesting DPI awareness via external means (e.g. calling SetProcessDpiAwarenessContext)
  *  and does not cause SDL to use a virtualized coordinate system, so it will generally give you 1 SDL coordinate = 1 pixel
  *  even on high-DPI displays.
- * 
+ *
  *  For more information, see:
  *  https://docs.microsoft.com/en-us/windows/win32/hidpi/high-dpi-desktop-application-development-on-windows
- * 
+ *
  *  This variable can be set to the following values:
  *    ""             - Do not change the DPI awareness (default).
  *    "unaware"      - Declare the process as DPI unaware. (Windows 8.1 and later).
@@ -2062,16 +2097,16 @@
 
 /**
  * \brief Uses DPI-scaled points as the SDL coordinate system on Windows.
- * 
+ *
  *  This changes the SDL coordinate system units to be DPI-scaled points, rather than pixels everywhere.
  *  This means windows will be appropriately sized, even when created on high-DPI displays with scaling.
- * 
+ *
  *  e.g. requesting a 640x480 window from SDL, on a display with 125% scaling in Windows display settings,
  *  will create a window with an 800x600 client area (in pixels).
  *
  *  Setting this to "1" implicitly requests process DPI awareness (setting SDL_WINDOWS_DPI_AWARENESS is unnecessary),
  *  and forces SDL_WINDOW_ALLOW_HIGHDPI on all windows.
- * 
+ *
  *  This variable can be set to the following values:
  *    "0"       - SDL coordinates equal Windows coordinates. No automatic window resizing when dragging
  *                between monitors with different scale factors (unless this is performed by
@@ -2082,7 +2117,7 @@
 #define SDL_HINT_WINDOWS_DPI_SCALING "SDL_WINDOWS_DPI_SCALING"
 
 /**
- *  \brief  A variable controlling whether the window frame and title bar are interactive when the cursor is hidden 
+ *  \brief  A variable controlling whether the window frame and title bar are interactive when the cursor is hidden
  *
  *  This variable can be set to the following values:
  *    "0"       - The window frame is not interactive when the cursor is hidden (no move, resize, etc)
@@ -2093,7 +2128,7 @@
 #define SDL_HINT_WINDOW_FRAME_USABLE_WHILE_CURSOR_HIDDEN    "SDL_WINDOW_FRAME_USABLE_WHILE_CURSOR_HIDDEN"
 
 /**
-*  \brief  A variable controlling whether the window is activated when the SDL_ShowWindow function is called 
+*  \brief  A variable controlling whether the window is activated when the SDL_ShowWindow function is called
 *
 *  This variable can be set to the following values:
 *    "0"       - The window is activated when the SDL_ShowWindow function is called
--- a/release/macos/ft2-clone-macos.app/Contents/Frameworks/SDL2.framework/Versions/A/Headers/SDL_joystick.h
+++ b/release/macos/ft2-clone-macos.app/Contents/Frameworks/SDL2.framework/Versions/A/Headers/SDL_joystick.h
@@ -44,6 +44,7 @@
 #include <SDL2/SDL_stdinc.h>
 #include <SDL2/SDL_error.h>
 #include <SDL2/SDL_guid.h>
+#include <SDL2/SDL_mutex.h>
 
 #include <SDL2/begin_code.h>
 /* Set up for C function definitions, even when using C++ */
@@ -66,6 +67,9 @@
 /**
  * The joystick structure used to identify an SDL joystick
  */
+#ifdef SDL_THREAD_SAFETY_ANALYSIS
+extern SDL_mutex *SDL_joystick_lock;
+#endif
 struct _SDL_Joystick;
 typedef struct _SDL_Joystick SDL_Joystick;
 
@@ -131,7 +135,7 @@
  *
  * \since This function is available since SDL 2.0.7.
  */
-extern DECLSPEC void SDLCALL SDL_LockJoysticks(void);
+extern DECLSPEC void SDLCALL SDL_LockJoysticks(void) SDL_ACQUIRE(SDL_joystick_lock);
 
 
 /**
@@ -146,7 +150,7 @@
  *
  * \since This function is available since SDL 2.0.7.
  */
-extern DECLSPEC void SDLCALL SDL_UnlockJoysticks(void);
+extern DECLSPEC void SDLCALL SDL_UnlockJoysticks(void) SDL_RELEASE(SDL_joystick_lock);
 
 /**
  * Count the number of joysticks attached to the system.
@@ -284,13 +288,12 @@
 /**
  * Get the instance ID of a joystick.
  *
- * This can be called before any joysticks are opened. If the index is out of
- * range, this function will return -1.
+ * This can be called before any joysticks are opened.
  *
  * \param device_index the index of the joystick to query (the N'th joystick
  *                     on the system
  * \returns the instance id of the selected joystick. If called on an invalid
- *          index, this function returns zero
+ *          index, this function returns -1.
  *
  * \since This function is available since SDL 2.0.6.
  */
--- a/release/macos/ft2-clone-macos.app/Contents/Frameworks/SDL2.framework/Versions/A/Headers/SDL_keycode.h
+++ b/release/macos/ft2-clone-macos.app/Contents/Frameworks/SDL2.framework/Versions/A/Headers/SDL_keycode.h
@@ -40,7 +40,7 @@
  *  an SDLK_* constant for those keys that do not generate characters.
  *
  *  A special exception is the number keys at the top of the keyboard which
- *  always map to SDLK_0...SDLK_9, regardless of layout.
+ *  map to SDLK_0...SDLK_9 on AZERTY layouts.
  */
 typedef Sint32 SDL_Keycode;
 
--- a/release/macos/ft2-clone-macos.app/Contents/Frameworks/SDL2.framework/Versions/A/Headers/SDL_main.h
+++ b/release/macos/ft2-clone-macos.app/Contents/Frameworks/SDL2.framework/Versions/A/Headers/SDL_main.h
@@ -263,6 +263,13 @@
  */
 extern DECLSPEC int SDLCALL SDL_GDKRunApp(SDL_main_func mainFunction, void *reserved);
 
+/**
+ * Callback from the application to let the suspend continue.
+ *
+ * \since This function is available since SDL 2.28.0.
+ */
+extern DECLSPEC void SDLCALL SDL_GDKSuspendComplete(void);
+
 #endif /* __GDK__ */
 
 #ifdef __cplusplus
--- a/release/macos/ft2-clone-macos.app/Contents/Frameworks/SDL2.framework/Versions/A/Headers/SDL_mouse.h
+++ b/release/macos/ft2-clone-macos.app/Contents/Frameworks/SDL2.framework/Versions/A/Headers/SDL_mouse.h
@@ -198,14 +198,10 @@
 /**
  * Set relative mouse mode.
  *
- * While the mouse is in relative mode, the cursor is hidden, and the driver
- * will try to report continuous motion in the current window. Only relative
- * motion events will be delivered, the mouse position will not change.
+ * While the mouse is in relative mode, the cursor is hidden, the mouse
+ * position is constrained to the window, and SDL will report continuous
+ * relative mouse motion even if the mouse is at the edge of the window.
  *
- * Note that this function will not be able to provide continuous relative
- * motion when used over Microsoft Remote Desktop, instead motion is limited
- * to the bounds of the screen.
- *
  * This function will flush any pending mouse motion.
  *
  * \param enabled SDL_TRUE to enable relative mode, SDL_FALSE to disable.
@@ -388,6 +384,9 @@
 
 /**
  * Get the default cursor.
+ *
+ * You do not have to call SDL_FreeCursor() on the return value, but it is
+ * safe to do so.
  *
  * \returns the default cursor on success or NULL on failure.
  *
--- a/release/macos/ft2-clone-macos.app/Contents/Frameworks/SDL2.framework/Versions/A/Headers/SDL_mutex.h
+++ b/release/macos/ft2-clone-macos.app/Contents/Frameworks/SDL2.framework/Versions/A/Headers/SDL_mutex.h
@@ -31,6 +31,80 @@
 #include <SDL2/SDL_stdinc.h>
 #include <SDL2/SDL_error.h>
 
+/******************************************************************************/
+/* Enable thread safety attributes only with clang.
+ * The attributes can be safely erased when compiling with other compilers.
+ */
+#if defined(SDL_THREAD_SAFETY_ANALYSIS) && \
+    defined(__clang__) && (!defined(SWIG))
+#define SDL_THREAD_ANNOTATION_ATTRIBUTE__(x)   __attribute__((x))
+#else
+#define SDL_THREAD_ANNOTATION_ATTRIBUTE__(x)   /* no-op */
+#endif
+
+#define SDL_CAPABILITY(x) \
+  SDL_THREAD_ANNOTATION_ATTRIBUTE__(capability(x))
+
+#define SDL_SCOPED_CAPABILITY \
+  SDL_THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable)
+
+#define SDL_GUARDED_BY(x) \
+  SDL_THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x))
+
+#define SDL_PT_GUARDED_BY(x) \
+  SDL_THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_by(x))
+
+#define SDL_ACQUIRED_BEFORE(x) \
+  SDL_THREAD_ANNOTATION_ATTRIBUTE__(acquired_before(x))
+
+#define SDL_ACQUIRED_AFTER(x) \
+  SDL_THREAD_ANNOTATION_ATTRIBUTE__(acquired_after(x))
+
+#define SDL_REQUIRES(x) \
+  SDL_THREAD_ANNOTATION_ATTRIBUTE__(requires_capability(x))
+
+#define SDL_REQUIRES_SHARED(x) \
+  SDL_THREAD_ANNOTATION_ATTRIBUTE__(requires_shared_capability(x))
+
+#define SDL_ACQUIRE(x) \
+  SDL_THREAD_ANNOTATION_ATTRIBUTE__(acquire_capability(x))
+
+#define SDL_ACQUIRE_SHARED(x) \
+  SDL_THREAD_ANNOTATION_ATTRIBUTE__(acquire_shared_capability(x))
+
+#define SDL_RELEASE(x) \
+  SDL_THREAD_ANNOTATION_ATTRIBUTE__(release_capability(x))
+
+#define SDL_RELEASE_SHARED(x) \
+  SDL_THREAD_ANNOTATION_ATTRIBUTE__(release_shared_capability(x))
+
+#define SDL_RELEASE_GENERIC(x) \
+  SDL_THREAD_ANNOTATION_ATTRIBUTE__(release_generic_capability(x))
+
+#define SDL_TRY_ACQUIRE(x, y) \
+  SDL_THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_capability(x, y))
+
+#define SDL_TRY_ACQUIRE_SHARED(x, y) \
+  SDL_THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_shared_capability(x, y))
+
+#define SDL_EXCLUDES(x) \
+  SDL_THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(x))
+
+#define SDL_ASSERT_CAPABILITY(x) \
+  SDL_THREAD_ANNOTATION_ATTRIBUTE__(assert_capability(x))
+
+#define SDL_ASSERT_SHARED_CAPABILITY(x) \
+  SDL_THREAD_ANNOTATION_ATTRIBUTE__(assert_shared_capability(x))
+
+#define SDL_RETURN_CAPABILITY(x) \
+  SDL_THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x))
+
+#define SDL_NO_THREAD_SAFETY_ANALYSIS \
+  SDL_THREAD_ANNOTATION_ATTRIBUTE__(no_thread_safety_analysis)
+
+/******************************************************************************/
+
+
 #include <SDL2/begin_code.h>
 /* Set up for C function definitions, even when using C++ */
 #ifdef __cplusplus
@@ -96,7 +170,7 @@
  *
  * \since This function is available since SDL 2.0.0.
  */
-extern DECLSPEC int SDLCALL SDL_LockMutex(SDL_mutex * mutex);
+extern DECLSPEC int SDLCALL SDL_LockMutex(SDL_mutex * mutex) SDL_ACQUIRE(mutex);
 #define SDL_mutexP(m)   SDL_LockMutex(m)
 
 /**
@@ -119,7 +193,7 @@
  * \sa SDL_LockMutex
  * \sa SDL_UnlockMutex
  */
-extern DECLSPEC int SDLCALL SDL_TryLockMutex(SDL_mutex * mutex);
+extern DECLSPEC int SDLCALL SDL_TryLockMutex(SDL_mutex * mutex) SDL_TRY_ACQUIRE(0, mutex);
 
 /**
  * Unlock the mutex.
@@ -138,7 +212,7 @@
  *
  * \since This function is available since SDL 2.0.0.
  */
-extern DECLSPEC int SDLCALL SDL_UnlockMutex(SDL_mutex * mutex);
+extern DECLSPEC int SDLCALL SDL_UnlockMutex(SDL_mutex * mutex) SDL_RELEASE(mutex);
 #define SDL_mutexV(m)   SDL_UnlockMutex(m)
 
 /**
@@ -276,7 +350,7 @@
  * successful it will atomically decrement the semaphore value.
  *
  * \param sem the semaphore to wait on
- * \param ms the length of the timeout, in milliseconds
+ * \param timeout the length of the timeout, in milliseconds
  * \returns 0 if the wait succeeds, `SDL_MUTEX_TIMEDOUT` if the wait does not
  *          succeed in the allotted time, or a negative error code on failure;
  *          call SDL_GetError() for more information.
@@ -290,7 +364,7 @@
  * \sa SDL_SemValue
  * \sa SDL_SemWait
  */
-extern DECLSPEC int SDLCALL SDL_SemWaitTimeout(SDL_sem * sem, Uint32 ms);
+extern DECLSPEC int SDLCALL SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout);
 
 /**
  * Atomically increment a semaphore's value and wake waiting threads.
--- a/release/macos/ft2-clone-macos.app/Contents/Frameworks/SDL2.framework/Versions/A/Headers/SDL_opengl_glext.h
+++ b/release/macos/ft2-clone-macos.app/Contents/Frameworks/SDL2.framework/Versions/A/Headers/SDL_opengl_glext.h
@@ -1,4 +1,8 @@
-#ifndef __gl_glext_h_
+/* SDL modified the include guard to be compatible with Mesa and Apple include guards:
+ * - Mesa uses: __gl_glext_h_
+ * - Apple uses: __glext_h_  */
+#if !defined(__glext_h_) && !defined(__gl_glext_h_)
+#define __glext_h_ 1
 #define __gl_glext_h_ 1
 
 #ifdef __cplusplus
--- a/release/macos/ft2-clone-macos.app/Contents/Frameworks/SDL2.framework/Versions/A/Headers/SDL_power.h
+++ b/release/macos/ft2-clone-macos.app/Contents/Frameworks/SDL2.framework/Versions/A/Headers/SDL_power.h
@@ -48,7 +48,6 @@
     SDL_POWERSTATE_CHARGED       /**< Plugged in, battery charged */
 } SDL_PowerState;
 
-
 /**
  * Get the current power supply details.
  *
@@ -65,17 +64,17 @@
  * It's possible a platform can only report battery percentage or time left
  * but not both.
  *
- * \param secs seconds of battery life left, you can pass a NULL here if you
- *             don't care, will return -1 if we can't determine a value, or
- *             we're not running on a battery
- * \param pct percentage of battery life left, between 0 and 100, you can pass
- *            a NULL here if you don't care, will return -1 if we can't
- *            determine a value, or we're not running on a battery
+ * \param seconds seconds of battery life left, you can pass a NULL here if
+ *                you don't care, will return -1 if we can't determine a
+ *                value, or we're not running on a battery
+ * \param percent percentage of battery life left, between 0 and 100, you can
+ *                pass a NULL here if you don't care, will return -1 if we
+ *                can't determine a value, or we're not running on a battery
  * \returns an SDL_PowerState enum representing the current battery state.
  *
  * \since This function is available since SDL 2.0.0.
  */
-extern DECLSPEC SDL_PowerState SDLCALL SDL_GetPowerInfo(int *secs, int *pct);
+extern DECLSPEC SDL_PowerState SDLCALL SDL_GetPowerInfo(int *seconds, int *percent);
 
 /* Ends C function definitions when using C++ */
 #ifdef __cplusplus
--- a/release/macos/ft2-clone-macos.app/Contents/Frameworks/SDL2.framework/Versions/A/Headers/SDL_render.h
+++ b/release/macos/ft2-clone-macos.app/Contents/Frameworks/SDL2.framework/Versions/A/Headers/SDL_render.h
@@ -1731,6 +1731,11 @@
  *
  * \param renderer the rendering context
  *
+ * \threadsafety You may only call this function on the main thread. If this
+ *               happens to work on a background thread on any given platform
+ *               or backend, it's purely by luck and you should not rely on it
+ *               to work next time.
+ *
  * \since This function is available since SDL 2.0.0.
  *
  * \sa SDL_RenderClear
--- a/release/macos/ft2-clone-macos.app/Contents/Frameworks/SDL2.framework/Versions/A/Headers/SDL_revision.h
+++ b/release/macos/ft2-clone-macos.app/Contents/Frameworks/SDL2.framework/Versions/A/Headers/SDL_revision.h
@@ -1,7 +1,7 @@
 /* Generated by updaterev.sh, do not edit */
 #ifdef SDL_VENDOR_INFO
-#define SDL_REVISION "SDL-release-2.26.5-0-gac13ca9ab (" SDL_VENDOR_INFO ")"
+#define SDL_REVISION "SDL-release-2.28.0-0-gffa78e6be (" SDL_VENDOR_INFO ")"
 #else
-#define SDL_REVISION "SDL-release-2.26.5-0-gac13ca9ab"
+#define SDL_REVISION "SDL-release-2.28.0-0-gffa78e6be"
 #endif
 #define SDL_REVISION_NUMBER 0
--- a/release/macos/ft2-clone-macos.app/Contents/Frameworks/SDL2.framework/Versions/A/Headers/SDL_sensor.h
+++ b/release/macos/ft2-clone-macos.app/Contents/Frameworks/SDL2.framework/Versions/A/Headers/SDL_sensor.h
@@ -84,7 +84,7 @@
  * The accelerometer returns the current acceleration in SI meters per
  * second squared. This measurement includes the force of gravity, so
  * a device at rest will have an value of SDL_STANDARD_GRAVITY away
- * from the center of the earth.
+ * from the center of the earth, which is a positive Y value.
  *
  * values[0]: Acceleration on the x axis
  * values[1]: Acceleration on the y axis
--- a/release/macos/ft2-clone-macos.app/Contents/Frameworks/SDL2.framework/Versions/A/Headers/SDL_stdinc.h
+++ b/release/macos/ft2-clone-macos.app/Contents/Frameworks/SDL2.framework/Versions/A/Headers/SDL_stdinc.h
@@ -30,12 +30,6 @@
 
 #include <SDL2/SDL_config.h>
 
-#ifdef __APPLE__
-#ifndef _DARWIN_C_SOURCE
-#define _DARWIN_C_SOURCE 1 /* for memset_pattern4() */
-#endif
-#endif
-
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
 #endif
@@ -85,7 +79,9 @@
    Visual Studio.  See http://msdn.microsoft.com/en-us/library/4hwaceh6.aspx
    for more information.
 */
-#  define _USE_MATH_DEFINES
+#  ifndef _USE_MATH_DEFINES
+#    define _USE_MATH_DEFINES
+#  endif
 # endif
 # include <math.h>
 #endif
@@ -528,9 +524,7 @@
 /* Note that memset() is a byte assignment and this is a 32-bit assignment, so they're not directly equivalent. */
 SDL_FORCE_INLINE void SDL_memset4(void *dst, Uint32 val, size_t dwords)
 {
-#ifdef __APPLE__
-    memset_pattern4(dst, &val, dwords * 4);
-#elif defined(__GNUC__) && defined(__i386__)
+#if defined(__GNUC__) && defined(__i386__)
     int u0, u1, u2;
     __asm__ __volatile__ (
         "cld \n\t"
@@ -694,7 +688,7 @@
                                          size_t * outbytesleft);
 
 /**
- * This function converts a string between encodings in one pass, returning a
+ * This function converts a buffer or string between encodings in one pass, returning a
  * string that must be freed with SDL_free() or NULL on error.
  *
  * \since This function is available since SDL 2.0.0.
@@ -721,6 +715,20 @@
 #ifndef HAVE_STRLCAT
 size_t strlcat(char* dst, const char* src, size_t size);
 #endif
+
+#ifndef HAVE_WCSLCPY
+size_t wcslcpy(wchar_t *dst, const wchar_t *src, size_t size);
+#endif
+
+#ifndef HAVE_WCSLCAT
+size_t wcslcat(wchar_t *dst, const wchar_t *src, size_t size);
+#endif
+
+/* Starting LLVM 16, the analyser errors out if these functions do not have
+   their prototype defined (clang-diagnostic-implicit-function-declaration) */
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
 
 #define SDL_malloc malloc
 #define SDL_calloc calloc
--- a/release/macos/ft2-clone-macos.app/Contents/Frameworks/SDL2.framework/Versions/A/Headers/SDL_thread.h
+++ b/release/macos/ft2-clone-macos.app/Contents/Frameworks/SDL2.framework/Versions/A/Headers/SDL_thread.h
@@ -35,7 +35,7 @@
 #include <SDL2/SDL_atomic.h>
 #include <SDL2/SDL_mutex.h>
 
-#if defined(__WIN32__) || defined(__GDK__)
+#if (defined(__WIN32__) || defined(__GDK__)) && !defined(__WINRT__)
 #include <process.h> /* _beginthreadex() and _endthreadex() */
 #endif
 #if defined(__OS2__) /* for _beginthread() and _endthread() */
@@ -88,7 +88,7 @@
 typedef int (SDLCALL * SDL_ThreadFunction) (void *data);
 
 
-#if defined(__WIN32__) || defined(__GDK__)
+#if (defined(__WIN32__) || defined(__GDK__)) && !defined(__WINRT__)
 /**
  *  \file SDL_thread.h
  *
--- a/release/macos/ft2-clone-macos.app/Contents/Frameworks/SDL2.framework/Versions/A/Headers/SDL_version.h
+++ b/release/macos/ft2-clone-macos.app/Contents/Frameworks/SDL2.framework/Versions/A/Headers/SDL_version.h
@@ -58,8 +58,8 @@
 /* Printable format: "%d.%d.%d", MAJOR, MINOR, PATCHLEVEL
 */
 #define SDL_MAJOR_VERSION   2
-#define SDL_MINOR_VERSION   26
-#define SDL_PATCHLEVEL      5
+#define SDL_MINOR_VERSION   28
+#define SDL_PATCHLEVEL      0
 
 /**
  * Macro to determine SDL version program was compiled against.
--- a/release/macos/ft2-clone-macos.app/Contents/Frameworks/SDL2.framework/Versions/A/Headers/SDL_video.h
+++ b/release/macos/ft2-clone-macos.app/Contents/Frameworks/SDL2.framework/Versions/A/Headers/SDL_video.h
@@ -187,7 +187,8 @@
     SDL_DISPLAYEVENT_NONE,          /**< Never used */
     SDL_DISPLAYEVENT_ORIENTATION,   /**< Display orientation has changed to data1 */
     SDL_DISPLAYEVENT_CONNECTED,     /**< Display has been added to the system */
-    SDL_DISPLAYEVENT_DISCONNECTED   /**< Display has been removed from the system */
+    SDL_DISPLAYEVENT_DISCONNECTED,  /**< Display has been removed from the system */
+    SDL_DISPLAYEVENT_MOVED          /**< Display has changed position */
 } SDL_DisplayEventID;
 
 /**
@@ -1275,6 +1276,17 @@
                                                     Uint32 flags);
 
 /**
+ * Return whether the window has a surface associated with it.
+ *
+ * \returns SDL_TRUE if there is a surface associated with the window, or SDL_FALSE otherwise.
+ *
+ * \since This function is available since SDL 2.28.0.
+ *
+ * \sa SDL_GetWindowSurface
+ */
+extern DECLSPEC SDL_bool SDLCALL SDL_HasWindowSurface(SDL_Window *window);
+
+/**
  * Get the SDL surface associated with the window.
  *
  * A new surface will be created with the optimal format for the window, if
@@ -1294,6 +1306,8 @@
  *
  * \since This function is available since SDL 2.0.0.
  *
+ * \sa SDL_DestroyWindowSurface
+ * \sa SDL_HasWindowSurface
  * \sa SDL_UpdateWindowSurface
  * \sa SDL_UpdateWindowSurfaceRects
  */
@@ -1328,7 +1342,7 @@
  *
  * \param window the window to update
  * \param rects an array of SDL_Rect structures representing areas of the
- *              surface to copy
+ *              surface to copy, in pixels
  * \param numrects the number of rectangles
  * \returns 0 on success or a negative error code on failure; call
  *          SDL_GetError() for more information.
@@ -1341,6 +1355,20 @@
 extern DECLSPEC int SDLCALL SDL_UpdateWindowSurfaceRects(SDL_Window * window,
                                                          const SDL_Rect * rects,
                                                          int numrects);
+
+/**
+ * Destroy the surface associated with the window.
+ *
+ * \param window the window to update
+ * \returns 0 on success or a negative error code on failure; call
+ *          SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.28.0.
+ *
+ * \sa SDL_GetWindowSurface
+ * \sa SDL_HasWindowSurface
+ */
+extern DECLSPEC int SDLCALL SDL_DestroyWindowSurface(SDL_Window *window);
 
 /**
  * Set a window's input grab mode.
--- a/release/macos/ft2-clone-macos.app/Contents/Frameworks/SDL2.framework/Versions/A/Headers/begin_code.h
+++ b/release/macos/ft2-clone-macos.app/Contents/Frameworks/SDL2.framework/Versions/A/Headers/begin_code.h
@@ -28,10 +28,10 @@
  */
 
 /* This shouldn't be nested -- included it around code only. */
-#ifdef _begin_code_h
+#ifdef SDL_begin_code_h
 #error Nested inclusion of begin_code.h
 #endif
-#define _begin_code_h
+#define SDL_begin_code_h
 
 #ifndef SDL_DEPRECATED
 #  if defined(__GNUC__) && (__GNUC__ >= 4)  /* technically, this arrived in gcc 3.1, but oh well. */
@@ -171,17 +171,17 @@
 #define SDL_FALLTHROUGH [[fallthrough]]
 #else
 #if defined(__has_attribute)
-#define _HAS_FALLTHROUGH __has_attribute(__fallthrough__)
+#define SDL_HAS_FALLTHROUGH __has_attribute(__fallthrough__)
 #else
-#define _HAS_FALLTHROUGH 0
+#define SDL_HAS_FALLTHROUGH 0
 #endif /* __has_attribute */
-#if _HAS_FALLTHROUGH && \
+#if SDL_HAS_FALLTHROUGH && \
    ((defined(__GNUC__) && __GNUC__ >= 7) || \
     (defined(__clang_major__) && __clang_major__ >= 10))
 #define SDL_FALLTHROUGH __attribute__((__fallthrough__))
 #else
 #define SDL_FALLTHROUGH do {} while (0) /* fallthrough */
-#endif /* _HAS_FALLTHROUGH */
-#undef _HAS_FALLTHROUGH
+#endif /* SDL_HAS_FALLTHROUGH */
+#undef SDL_HAS_FALLTHROUGH
 #endif /* C++17 or C2x */
 #endif /* SDL_FALLTHROUGH not defined */
--- a/release/macos/ft2-clone-macos.app/Contents/Frameworks/SDL2.framework/Versions/A/Headers/close_code.h
+++ b/release/macos/ft2-clone-macos.app/Contents/Frameworks/SDL2.framework/Versions/A/Headers/close_code.h
@@ -26,10 +26,10 @@
  *  after you finish any function and structure declarations in your headers
  */
 
-#ifndef _begin_code_h
+#ifndef SDL_begin_code_h
 #error close_code.h included without matching begin_code.h
 #endif
-#undef _begin_code_h
+#undef SDL_begin_code_h
 
 /* Reset structure packing at previous byte alignment */
 #if defined(_MSC_VER) || defined(__MWERKS__) || defined(__BORLANDC__)
--- a/release/macos/ft2-clone-macos.app/Contents/Frameworks/SDL2.framework/Versions/A/Resources/CMake/sdl2-config.cmake
+++ b/release/macos/ft2-clone-macos.app/Contents/Frameworks/SDL2.framework/Versions/A/Resources/CMake/sdl2-config.cmake
@@ -57,6 +57,8 @@
             INTERFACE_LINK_OPTIONS "SHELL:-F \"${SDL2_FRAMEWORK_PARENT_PATH}\";SHELL:-framework SDL2"
             COMPATIBLE_INTERFACE_BOOL "SDL2_SHARED"
             INTERFACE_SDL2_SHARED "ON"
+            COMPATIBLE_INTERFACE_STRING "SDL_VERSION"
+            INTERFACE_SDL_VERSION "SDL2"
     )
 endif()
 set(SDL2_SDL2_FOUND TRUE)
--- a/release/macos/ft2-clone-macos.app/Contents/Frameworks/SDL2.framework/Versions/A/Resources/Info.plist
+++ b/release/macos/ft2-clone-macos.app/Contents/Frameworks/SDL2.framework/Versions/A/Resources/Info.plist
@@ -3,7 +3,7 @@
 <plist version="1.0">
 <dict>
 	<key>BuildMachineOSBuild</key>
-	<string>22D68</string>
+	<string>22F66</string>
 	<key>CFBundleDevelopmentRegion</key>
 	<string>English</string>
 	<key>CFBundleExecutable</key>
@@ -19,7 +19,7 @@
 	<key>CFBundlePackageType</key>
 	<string>FMWK</string>
 	<key>CFBundleShortVersionString</key>
-	<string>2.26.5</string>
+	<string>2.28.0</string>
 	<key>CFBundleSignature</key>
 	<string>SDLX</string>
 	<key>CFBundleSupportedPlatforms</key>
@@ -27,7 +27,7 @@
 		<string>MacOSX</string>
 	</array>
 	<key>CFBundleVersion</key>
-	<string>2.26.5</string>
+	<string>2.28.0</string>
 	<key>DTCompiler</key>
 	<string>com.apple.compilers.llvm.clang.1_0</string>
 	<key>DTPlatformBuild</key>
@@ -41,9 +41,9 @@
 	<key>DTSDKName</key>
 	<string>macosx13.3</string>
 	<key>DTXcode</key>
-	<string>1430</string>
+	<string>1431</string>
 	<key>DTXcodeBuild</key>
-	<string>14E222b</string>
+	<string>14E300c</string>
 	<key>LSMinimumSystemVersion</key>
 	<string>10.11</string>
 </dict>
--- a/release/macos/ft2-clone-macos.app/Contents/Frameworks/SDL2.framework/Versions/A/_CodeSignature/CodeResources
+++ b/release/macos/ft2-clone-macos.app/Contents/Frameworks/SDL2.framework/Versions/A/_CodeSignature/CodeResources
@@ -10,11 +10,11 @@
 		</data>
 		<key>Resources/CMake/sdl2-config.cmake</key>
 		<data>
-		aottfZnkkRrcejRrYqK2L/49GIU=
+		s2hXhDxzy/ilC+gLamGy/Kq13jo=
 		</data>
 		<key>Resources/Info.plist</key>
 		<data>
-		ECcyTBfZPucOFnTMf7BSonyduBg=
+		MP8SsWNX9fsyVRo11YwxKezmPug=
 		</data>
 		<key>Resources/License.txt</key>
 		<data>
@@ -57,11 +57,11 @@
 		<dict>
 			<key>hash</key>
 			<data>
-			TaFJjJYsOXON8iaLEX5xgfJH0FI=
+			FTCyRgMQ1IzdGYV2XbCDSQ7JNec=
 			</data>
 			<key>hash2</key>
 			<data>
-			nmWpPus/eISidEuuFqvVp/7XY07q4kHIRaT63X/reVA=
+			4iFngSAorzMM520V+2V1sriu9mL12sLlPrhNfgT12Ck=
 			</data>
 		</dict>
 		<key>Headers/SDL_audio.h</key>
@@ -68,11 +68,11 @@
 		<dict>
 			<key>hash</key>
 			<data>
-			16xbool8mbuYWNC2lmIqMxUmlZQ=
+			ATRDpv42XjNUWqjKPDAPYqIqvDY=
 			</data>
 			<key>hash2</key>
 			<data>
-			fqqrBPvDux0Z4lIvqQKdhOVSZRLcTBx0Qva8cbLp418=
+			MThYj7HEVNC7MdUTbzgyHDqlDMDS9g664b6M5d7tsdY=
 			</data>
 		</dict>
 		<key>Headers/SDL_bits.h</key>
@@ -90,11 +90,11 @@
 		<dict>
 			<key>hash</key>
 			<data>
-			zzSdvjZ9hKJxyC3VzOOwKmq61/U=
+			ThQw2vcWPo/mLtvKmhQrjhSQhLk=
 			</data>
 			<key>hash2</key>
 			<data>
-			BD+r9teOyEpTHM6NwvtQPhrazAj5e2wzwqQ/EqWKgVg=
+			o3UtzbWJqnTeh6+r+oLVdOzcJZ1b3XhfPINDjKHftu4=
 			</data>
 		</dict>
 		<key>Headers/SDL_clipboard.h</key>
@@ -156,11 +156,11 @@
 		<dict>
 			<key>hash</key>
 			<data>
-			MHpy1KvnqOf64f2781BUtUz0DEI=
+			j6/tuHiJfdv8YaI9k3fogDw4bNc=
 			</data>
 			<key>hash2</key>
 			<data>
-			AmEG80oborsu7cRbeBBS2zyDKvyxTT2kh0M7rYrm2HI=
+			P5KOVzR2wBlhdSw7biIJ3O78dnYnoGdi4pHxvyFcLdY=
 			</data>
 		</dict>
 		<key>Headers/SDL_error.h</key>
@@ -200,11 +200,11 @@
 		<dict>
 			<key>hash</key>
 			<data>
-			RMJ7KpEMN4aYVe8PvF0XyjhXVOc=
+			DGpJeIYXN/t/Yyqilband2kKOSk=
 			</data>
 			<key>hash2</key>
 			<data>
-			dJDgv9TNy/SgR2cADGxsSrwu1NZX2fYO830svryW4uc=
+			hgAaf8SQwVfc94yXKjNFA3VpsTCYwL65W5X6lXEnsgI=
 			</data>
 		</dict>
 		<key>Headers/SDL_gesture.h</key>
@@ -255,11 +255,11 @@
 		<dict>
 			<key>hash</key>
 			<data>
-			j33d96aUBrEwCVm9GpDBW1CXvVo=
+			M/nqf8jyrXJ9IrgLrVffOZG4Jlo=
 			</data>
 			<key>hash2</key>
 			<data>
-			WiHkNUFgiALKRxAIDQuaaU+Y6gKgtqw8YmZHPMtPyK4=
+			nCUBVEvtWTQ2Ab/H1a9n4I68tT572DhjMnne+N52bwY=
 			</data>
 		</dict>
 		<key>Headers/SDL_joystick.h</key>
@@ -266,11 +266,11 @@
 		<dict>
 			<key>hash</key>
 			<data>
-			85/bNiER9h5QVoRQLNEZGF5VD3E=
+			Y/dkiMb7+9Wmo8oyyOuh4igQK4o=
 			</data>
 			<key>hash2</key>
 			<data>
-			l5rSDksaaBXPl3GCffxGblOMgjvcufJSuuCglByf2yM=
+			d3rYIj9RV45IuiYZAbOQyNe3iR4DORkkqwYiSA81c6k=
 			</data>
 		</dict>
 		<key>Headers/SDL_keyboard.h</key>
@@ -288,11 +288,11 @@
 		<dict>
 			<key>hash</key>
 			<data>
-			h18H9W8J7wesaRF2OApJEb2RFrY=
+			j4z7vftDr05ahrBr5bZnBxZ3Ufs=
 			</data>
 			<key>hash2</key>
 			<data>
-			zv9BVIERwcpba8USfGXPAzRO/qMWBbB5bWLDqEwWSYU=
+			abAEws/ibkdlWSE/bP/uq0oIjcebU59aul5g4Lu0pbA=
 			</data>
 		</dict>
 		<key>Headers/SDL_loadso.h</key>
@@ -332,11 +332,11 @@
 		<dict>
 			<key>hash</key>
 			<data>
-			kDbuJzb/pBtb1iutYnW/hASbKgw=
+			j0/bBvlkrYcnXeoB6sWoCQiIlV0=
 			</data>
 			<key>hash2</key>
 			<data>
-			oIwpcrlXtl8XSnVMj+EmGESlisYv8O//EaDdoAd2xm0=
+			QOjL/8v8HMC/N+1jocNxIGBB5pifTDWxbwOvD7wJtRg=
 			</data>
 		</dict>
 		<key>Headers/SDL_messagebox.h</key>
@@ -376,11 +376,11 @@
 		<dict>
 			<key>hash</key>
 			<data>
-			wWyr5YJRLgkouejijZizd1f54ZE=
+			AL6jjX5llLXh3nscuX0MJQQJ7C0=
 			</data>
 			<key>hash2</key>
 			<data>
-			TN4Ft0Tl8FBtChEmqaC9q+ihzrGRO2+oE6f4FPqM754=
+			8R3uVCCs2wF9vtwJEqAi+xjYtAtJ1F6UIqCPUhiBwxU=
 			</data>
 		</dict>
 		<key>Headers/SDL_mutex.h</key>
@@ -387,11 +387,11 @@
 		<dict>
 			<key>hash</key>
 			<data>
-			LOlLQylQ4fAuTL6ywn5mc7YHggg=
+			c4s6haEURwhr1L/ZsIoQHgDC1Rw=
 			</data>
 			<key>hash2</key>
 			<data>
-			Xe+WvrizruQy0+uhYKV3UHknz8I5FnrW8AnSAwZJOfw=
+			L1kG6r9N1C+njGEvU0sAJeAVFwr6gkCCwGcBxsjDuNU=
 			</data>
 		</dict>
 		<key>Headers/SDL_name.h</key>
@@ -420,11 +420,11 @@
 		<dict>
 			<key>hash</key>
 			<data>
-			z3QoX44hLSqeS5sCphMCc8TAxno=
+			eOvalGUielSzNuOWWDLYkwqpYrg=
 			</data>
 			<key>hash2</key>
 			<data>
-			B2j/0LKCjlQl51aWvbslDd3Qc3C2JhJHMPu6C+u3CSs=
+			GrsoiRybBmG2/zdJ3iZx2l/hK+tbyxgzsta99ciezfg=
 			</data>
 		</dict>
 		<key>Headers/SDL_opengles.h</key>
@@ -519,11 +519,11 @@
 		<dict>
 			<key>hash</key>
 			<data>
-			smMe7j3MNIT7wXXFRtMvGPFulso=
+			SmO5g1nUZ1IAgDQGIlzbR8F5udg=
 			</data>
 			<key>hash2</key>
 			<data>
-			mwBQ8l0GVg+f+/FeIU3sMgo9JAY7X3uq4NPwOc27IL8=
+			Lmp/XdN6xQbqR/eAmoKFcpqk+MM65gGxjv1cLYUqG8c=
 			</data>
 		</dict>
 		<key>Headers/SDL_quit.h</key>
@@ -552,11 +552,11 @@
 		<dict>
 			<key>hash</key>
 			<data>
-			wLdzEIMoOvdQScGrBT0EjqjYTso=
+			sNcVNpmlpcvsqJmBOwyg6hjTWQ8=
 			</data>
 			<key>hash2</key>
 			<data>
-			xu0LmkwhR+b10K+nmKQ5XVpWOfKEHEEVTq0Ryswak3c=
+			1EY74HfczRb8zZ3CZfcoinmI8nVMwFaoIfcvG7kPBEE=
 			</data>
 		</dict>
 		<key>Headers/SDL_revision.h</key>
@@ -563,11 +563,11 @@
 		<dict>
 			<key>hash</key>
 			<data>
-			XNd3ECdYFSFaaMv/uj3NwyatWcY=
+			sRLTPAglYSZ19Pdm+afA2j47taM=
 			</data>
 			<key>hash2</key>
 			<data>
-			FzAYjxrloDaswbapi8PCqNyMRjro8m4e4gSgAHWrJ8o=
+			Fo7p72CdM/uZzX9nxLeCot/MrKYwSKmo0ESISIMTIOI=
 			</data>
 		</dict>
 		<key>Headers/SDL_rwops.h</key>
@@ -596,11 +596,11 @@
 		<dict>
 			<key>hash</key>
 			<data>
-			Pf6/Yj0hIgsUlhqj4UGylm+TjQs=
+			J+9woN1Qec074rah/rly1BHM5sY=
 			</data>
 			<key>hash2</key>
 			<data>
-			5fAvXcuJcCx8/Et36VSkGacoiTENdiTe2BanIplHa2Y=
+			sEfbN4S8Lpxm0XDblgOvnVV0fsgx/zo/q0s5h9OvhmE=
 			</data>
 		</dict>
 		<key>Headers/SDL_shape.h</key>
@@ -618,11 +618,11 @@
 		<dict>
 			<key>hash</key>
 			<data>
-			5MtebnJHZfnCFhT9MeT6pg3EoPI=
+			iliyExriwpoxEAgG8CI8CG8go54=
 			</data>
 			<key>hash2</key>
 			<data>
-			qf4ijhTzMO4g9aKUrU+z10KfGRbOKVg3jIUS7TKrovA=
+			I4aI+ExJq+16kZfDjF++Uaa2lHZjUWmuFc83IUDfuIk=
 			</data>
 		</dict>
 		<key>Headers/SDL_surface.h</key>
@@ -662,11 +662,11 @@
 		<dict>
 			<key>hash</key>
 			<data>
-			bCVCxCLiY7Rkx02GC2u37KSejsU=
+			rdWafQMEiS2pSqeEGdRXDjaU96Q=
 			</data>
 			<key>hash2</key>
 			<data>
-			Qhsj5cNniFikrpQc/wnB/IipdeR8tFkywQAEwSyernM=
+			pVkN+av2tjneOX9IafFyXjDRaWe/ROSrLwUQRfCrYYA=
 			</data>
 		</dict>
 		<key>Headers/SDL_timer.h</key>
@@ -706,11 +706,11 @@
 		<dict>
 			<key>hash</key>
 			<data>
-			QDqwH27Tmjz8nMPphdVAZqPqGt0=
+			BrMh/0kZeBHu8Xr+/5hS8IHcMfU=
 			</data>
 			<key>hash2</key>
 			<data>
-			nk6h9XDXojUkw/F8Ff7er08rfzKTzlMT0jLr2lPMgv8=
+			tIqaCIDNMsT9rQ9arELIo8WVF04pSMBtxaavylyyrK4=
 			</data>
 		</dict>
 		<key>Headers/SDL_video.h</key>
@@ -717,11 +717,11 @@
 		<dict>
 			<key>hash</key>
 			<data>
-			YAMYz1pUQobEWpC1EuOB5YmsIZc=
+			oDSfm7hvyakVAn3MJ/vPYpDiTi8=
 			</data>
 			<key>hash2</key>
 			<data>
-			bFi0k6PF8xpOpR6X0Wsidxl7LIWX2hVGjSysd6roB6A=
+			4kgMp+1L702uCbe5U3mPNYx/zonCSDmAoqKxZGMWlC0=
 			</data>
 		</dict>
 		<key>Headers/SDL_vulkan.h</key>
@@ -739,11 +739,11 @@
 		<dict>
 			<key>hash</key>
 			<data>
-			f6TnCZT882PpPk816tLLYBb5tJM=
+			BXr58UQDjOvu3YEpLqbL6MzdnEw=
 			</data>
 			<key>hash2</key>
 			<data>
-			G4bzpDXzXe091TEGmuQxF+N64ZDTNg32tUjyDAYJXmE=
+			lZjnBGKuQiSupwtm3kZTliIMMPlHVmUsVTRtQ7E0WMU=
 			</data>
 		</dict>
 		<key>Headers/close_code.h</key>
@@ -750,11 +750,11 @@
 		<dict>
 			<key>hash</key>
 			<data>
-			pzX1cw2hHQdMFCO0VcO1VVsfXUo=
+			b9BWGnHVTllZJNggBlv8S0bczLA=
 			</data>
 			<key>hash2</key>
 			<data>
-			+ybA2nqIwfLyUQ9Pf9ZLXUyXMGNS3xZMEowuIcqIrRQ=
+			/x8Gxc1GaIoziXOz/sebI7d0PytDiEWi8kWZfjkp0Ww=
 			</data>
 		</dict>
 		<key>Resources/CMake/sdl2-config-version.cmake</key>
@@ -772,11 +772,11 @@
 		<dict>
 			<key>hash</key>
 			<data>
-			aottfZnkkRrcejRrYqK2L/49GIU=
+			s2hXhDxzy/ilC+gLamGy/Kq13jo=
 			</data>
 			<key>hash2</key>
 			<data>
-			NtAgweQRe487Cy32/RioObq+KAq6SXdUsRtQZaAvT6U=
+			DuTUW8idzRp7WT1FT5x/m1C1SbVH0FKvKRKOgVlRVhU=
 			</data>
 		</dict>
 		<key>Resources/Info.plist</key>
@@ -783,11 +783,11 @@
 		<dict>
 			<key>hash</key>
 			<data>
-			ECcyTBfZPucOFnTMf7BSonyduBg=
+			MP8SsWNX9fsyVRo11YwxKezmPug=
 			</data>
 			<key>hash2</key>
 			<data>
-			4i5aYnvsU/2ssKdrpU5A9mYIX4q4fzaqinS7xOcPTyY=
+			JS+9bRfZuLgojqjIgCYRqSXUyJ5L/MJO+Cyss5R17Rs=
 			</data>
 		</dict>
 		<key>Resources/License.txt</key>
--- a/src/ft2_about.h
+++ b/src/ft2_about.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_about_h_
+#define _ft2_about_h_
 
 #include <stdint.h>
 
@@ -7,3 +8,5 @@
 void showAboutScreen(void);
 void hideAboutScreen(void);
 void exitAboutScreen(void);
+
+#endif
--- a/src/ft2_audio.h
+++ b/src/ft2_audio.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_audio_h_
+#define _ft2_audio_h_
 
 #include <stdint.h>
 #include <stdbool.h>
@@ -82,9 +83,9 @@
 	float fCurrVolumeL, fCurrVolumeR, fVolumeLDelta, fVolumeRDelta, fTargetVolumeL, fTargetVolumeR;
 } voice_t;
 
-#ifdef _MSC_VER
-#pragma pack(push)
-#pragma pack(1)
+#if defined(_MSC_VER) || defined(__plan9__)
+#pragma pack on
+#pragma pack on
 #endif
 typedef struct pattSyncData_t // used for audio/video sync queue (pack to save RAM)
 {
@@ -95,8 +96,8 @@
 __attribute__ ((packed))
 #endif
 pattSyncData_t;
-#ifdef _MSC_VER
-#pragma pack(pop)
+#if defined(_MSC_VER) || defined(__plan9__)
+#pragma pack off
 #endif
 
 typedef struct pattSync_t
@@ -166,3 +167,5 @@
 extern pattSync_t pattSync;
 
 extern volatile bool pattQueueClearing, chQueueClearing;
+
+#endif
--- a/src/ft2_audioselector.h
+++ b/src/ft2_audioselector.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_audioselector_h_
+#define _ft2_audioselector_h_
 
 #include <stdint.h>
 
@@ -19,3 +20,5 @@
 void sbAudInputSetPos(uint32_t pos);
 void freeAudioDeviceLists(void);
 void freeAudioDeviceSelectorBuffers(void);
+
+#endif
--- a/src/ft2_bmp.h
+++ b/src/ft2_bmp.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_bmp_h_
+#define _ft2_bmp_h_
 
 #include <stdint.h>
 #include <stdbool.h>
@@ -17,3 +18,5 @@
 
 bool loadBMPs(void);
 void freeBMPs(void);
+
+#endif
--- a/src/ft2_checkboxes.h
+++ b/src/ft2_checkboxes.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_checkboxes_h_
+#define _ft2_checkboxes_h_
 
 #include <stdint.h>
 #include <stdbool.h>
@@ -120,3 +121,5 @@
 void handleCheckBoxesWhileMouseDown(void);
 bool testCheckBoxMouseDown(void);
 void testCheckBoxMouseRelease(void);
+
+#endif
--- a/src/ft2_config.h
+++ b/src/ft2_config.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_config_h_
+#define _ft2_config_h_
 
 #include <stdint.h>
 #include <stdbool.h>
@@ -99,9 +100,9 @@
 	START_IN_FULLSCR = 128,
 };
 
-#ifdef _MSC_VER
-#pragma pack(push)
-#pragma pack(1)
+#if defined(_MSC_VER) || defined(__plan9__)
+#pragma pack on
+#pragma pack on
 #endif
 typedef struct highScoreType_t
 {
@@ -176,8 +177,8 @@
 #endif
 config_t;
 
-#ifdef _MSC_VER
-#pragma pack(pop)
+#if defined(_MSC_VER) || defined(__plan9__)
+#pragma pack off
 #endif
 
 void resetConfig(void);
@@ -291,3 +292,5 @@
 void sbMIDISens(uint32_t pos);
 
 extern config_t config;
+
+#endif
--- a/src/ft2_cpu.h
+++ b/src/ft2_cpu.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_cpu_h_
+#define _ft2_cpu_h_
 
 #include <stdint.h>
 
@@ -29,4 +30,6 @@
 #define CPU_BITS 32
 #define uintCPUWord_t uint32_t
 #define intCPUWord_t int32_t
+#endif
+
 #endif
--- a/src/ft2_diskop.h
+++ b/src/ft2_diskop.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_diskop_h_
+#define _ft2_diskop_h_
 
 #include <stdint.h>
 #include "ft2_unicode.h"
@@ -84,3 +85,5 @@
 void trimEntryName(char *name, bool isDir);
 void createFileOverwriteText(char *filename, char *buffer);
 bool fileExistsAnsi(char *str);
+
+#endif
--- a/src/ft2_edit.h
+++ b/src/ft2_edit.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_edit_h_
+#define _ft2_edit_h_
 
 #include <stdint.h>
 #include <SDL2/SDL.h>
@@ -77,3 +78,5 @@
 void remapTrack(void);
 void remapPattern(void);
 void remapSong(void);
+
+#endif
--- a/src/ft2_events.c
+++ b/src/ft2_events.c
@@ -36,9 +36,9 @@
 #define CRASH_TEXT "Oh no! The Fasttracker II clone has crashed...\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.\n" \
-                   "My email can be found at the bottom of www.16-bits.org."
+                   "My email is on the bottom of https://16-bits.org"
 
-static bool backupMadeAfterCrash, didDropFile;
+static bool backupMadeAfterCrash;
 
 #ifdef _WIN32
 #define SYSMSG_FILE_ARG (WM_USER+1)
@@ -237,6 +237,12 @@
 
 				UnmapViewOfFile(sharedMemBuf);
 				sharedMemBuf = NULL;
+
+				if (video.window != NULL)
+				{
+					SDL_RestoreWindow(video.window);
+					SDL_RaiseWindow(video.window);
+				}
 			}
 
 			CloseHandle(hMapFile);
@@ -449,9 +455,8 @@
 			loadDroppedFile(event.drop.file, true);
 			SDL_free(event.drop.file);
 
-			// kludge: allow focus-clickthrough after drag-n-drop
-			SDL_SetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, "1");
-			didDropFile = true;
+			SDL_RestoreWindow(video.window);
+			SDL_RaiseWindow(video.window);
 		}
 		else if (event.type == SDL_QUIT)
 		{
@@ -489,13 +494,6 @@
 		else if (event.type == SDL_MOUSEBUTTONUP)
 		{
 			mouseButtonUpHandler(event.button.button);
-
-			// kludge: we drag-n-dropped a file before this mouse click release, restore focus-clickthrough mode
-			if (didDropFile)
-			{
-				didDropFile = false;
-				SDL_SetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, "0");
-			}
 		}
 		else if (event.type == SDL_MOUSEBUTTONDOWN)
 		{
--- a/src/ft2_events.h
+++ b/src/ft2_events.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_events_h_
+#define _ft2_events_h_
 
 #include <SDL2/SDL.h>
 #include <stdint.h>
@@ -20,4 +21,6 @@
 #ifdef _WIN32
 bool handleSingleInstancing(int32_t argc, char **argv);
 void closeSingleInstancing(void);
+#endif
+
 #endif
--- a/src/ft2_gfxdata.h
+++ b/src/ft2_gfxdata.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_gfxdata_h_
+#define _ft2_gfxdata_h_
 
 #include <stdint.h>
 
@@ -43,3 +44,5 @@
 // ft2_bmp_gui.c
 extern const uint8_t checkboxGfxBMP[776];
 extern const uint8_t radiobuttonGfxBMP[404];
+
+#endif
--- a/src/ft2_gui.h
+++ b/src/ft2_gui.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_gui_h_
+#define _ft2_gui_h_
 
 #include <stdint.h>
 #include <stdbool.h>
@@ -120,3 +121,5 @@
 void hideTopScreen(void);
 void showTopScreen(bool restoreScreens);
 void showBottomScreen(void);
+
+#endif
--- a/src/ft2_header.h
+++ b/src/ft2_header.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_header_h_
+#define _ft2_header_h_
 
 #include <SDL2/SDL.h>
 #include <stdint.h>
@@ -12,7 +13,7 @@
 #endif
 #include "ft2_replayer.h"
 
-#define PROG_VER_STR "1.67"
+#define PROG_VER_STR "1.69"
 
 // do NOT change these! It will only mess things up...
 
@@ -99,3 +100,5 @@
 {
 	int8_t *origPtr, *ptr;
 } smpPtr_t;
+
+#endif
--- a/src/ft2_help.h
+++ b/src/ft2_help.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_help_h_
+#define _ft2_help_h_
 
 #include <stdint.h>
 
@@ -20,3 +21,5 @@
 void rbHelpHowToUseFT2(void);
 void rbHelpFAQ(void);
 void rbHelpKnownBugs(void);
+
+#endif
--- a/src/ft2_hpc.h
+++ b/src/ft2_hpc.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_hpc_h_
+#define _ft2_hpc_h_
 
 #include <stdint.h>
 #include <stdbool.h>
@@ -22,3 +23,5 @@
 void hpc_SetDurationInHz(hpc_t *hpc, uint32_t dHz);
 void hpc_ResetCounters(hpc_t *hpc);
 void hpc_Wait(hpc_t *hpc);
+
+#endif
--- a/src/ft2_inst_ed.c
+++ b/src/ft2_inst_ed.c
@@ -23,9 +23,9 @@
 #include "ft2_structs.h"
 #include "ft2_bmp.h"
 
-#ifdef _MSC_VER
-#pragma pack(push)
-#pragma pack(1)
+#if defined(_MSC_VER) || defined(__plan9__)
+#pragma pack on
+#pragma pack on
 #endif
 typedef struct patHdr_t
 {
--- a/src/ft2_inst_ed.h
+++ b/src/ft2_inst_ed.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_inst_ed_h_
+#define _ft2_inst_ed_h_
 
 #include <stdint.h>
 #include "ft2_header.h"
@@ -104,3 +105,5 @@
 void showInstEditorExt(void);
 void hideInstEditorExt(void);
 void toggleInstEditorExt(void);
+
+#endif
--- a/src/ft2_keyboard.h
+++ b/src/ft2_keyboard.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_keyboard_h_
+#define _ft2_keyboard_h_
 
 #include <stdint.h>
 #include <stdbool.h>
@@ -18,3 +19,5 @@
 void keyUpHandler(SDL_Scancode scancode, SDL_Keycode keycode);
 void keyDownHandler(SDL_Scancode scancode, SDL_Keycode keycode, bool keyWasRepeated);
 void readKeyModifiers(void);
+
+#endif
--- a/src/ft2_main.c
+++ b/src/ft2_main.c
@@ -95,7 +95,7 @@
 
 	// ALT+F4 is used in FT2, but is "close program" in Windows...
 #if SDL_MINOR_VERSION >= 24 || (SDL_MINOR_VERSION == 0 && SDL_PATCHLEVEL >= 4)
-	SDL_SetHint(SDL_HINT_WINDOWS_NO_CLOSE_ON_ALT_F4, "1");
+	SDL_SetHint("SDL_WINDOWS_NO_CLOSE_ON_ALT_F4", "1");
 #endif
 
 #ifdef _WIN32
--- a/src/ft2_midi.h
+++ b/src/ft2_midi.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_midi_h_
+#define _ft2_midi_h_
 
 #ifdef HAS_MIDI
 
@@ -36,5 +37,7 @@
 void sbMidiInputSetPos(uint32_t pos);
 bool testMidiInputDeviceListMouseDown(void);
 int32_t SDLCALL initMidiFunc(void *ptr);
+
+#endif
 
 #endif
--- a/src/ft2_module_loader.h
+++ b/src/ft2_module_loader.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_module_loader_h_
+#define _ft2_module_loader_h_
 
 #include <stdint.h>
 #include <stdbool.h>
@@ -23,3 +24,5 @@
 extern note_t *patternTmp[MAX_PATTERNS];
 extern instr_t *instrTmp[1+256];
 extern song_t songTmp;
+
+#endif
--- a/src/ft2_module_saver.h
+++ b/src/ft2_module_saver.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_module_saver_h_
+#define _ft2_module_saver_h_
 
 #include <stdint.h>
 #include <stdbool.h>
@@ -6,3 +7,5 @@
 
 void saveMusic(UNICHAR *filenameU);
 bool saveXM(UNICHAR *filenameU);
+
+#endif
--- a/src/ft2_mouse.c
+++ b/src/ft2_mouse.c
@@ -77,7 +77,9 @@
 
 	for (int32_t i = 0; i < NUM_CURSORS; i++)
 	{
-		const int32_t scaleFactor = video.yScale;
+		int32_t scaleFactor = video.yScale;
+		if (scaleFactor > 8) // just in case
+			scaleFactor = 8;
 
 		SDL_Surface *surface = SDL_CreateRGBSurface(0, MOUSE_CURSOR_W*scaleFactor, MOUSE_CURSOR_H*scaleFactor, 32, 0, 0, 0, 0);
 		if (surface == NULL)
--- a/src/ft2_mouse.h
+++ b/src/ft2_mouse.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_mouse_h_
+#define _ft2_mouse_h_
 
 #include <stdint.h>
 #include <stdbool.h>
@@ -49,3 +50,5 @@
 void handleLastGUIObjectDown(void);
 void readMouseXY(void);
 void resetMouseBusyAnimation(void);
+
+#endif
--- a/src/ft2_nibbles.h
+++ b/src/ft2_nibbles.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_nibbles_h_
+#define _ft2_nibbles_h_
 
 #include <stdint.h>
 #include <stdbool.h>
@@ -24,3 +25,5 @@
 void nibblesToggleGrid(void);
 void nibblesToggleWrap(void);
 bool testNibblesCheatCodes(SDL_Keycode keycode);
+
+#endif
--- a/src/ft2_palette.h
+++ b/src/ft2_palette.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_palette_h_
+#define _ft2_palette_h_
 
 #include <stdint.h>
 #include <stdbool.h>
@@ -44,9 +45,9 @@
 	PAL_NUM
 };
 
-#ifdef _MSC_VER
-#pragma pack(push)
-#pragma pack(1)
+#if defined(_MSC_VER) || defined(__plan9__)
+#pragma pack on
+#pragma pack on
 #endif
 typedef struct pal16_t
 {
@@ -56,8 +57,8 @@
 __attribute__ ((packed))
 #endif
 pal16;
-#ifdef _MSC_VER
-#pragma pack(pop)
+#if defined(_MSC_VER) || defined(__plan9__)
+#pragma pack off
 #endif
 
 void setCustomPalColor(uint32_t color);
@@ -99,3 +100,5 @@
 void rbConfigPalUserDefined(void);
 
 extern uint8_t cfg_ColorNum;
+
+#endif
--- a/src/ft2_pattern_draw.h
+++ b/src/ft2_pattern_draw.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_pattern_draw_h_
+#define _ft2_pattern_draw_h_
 
 #include <stdint.h>
 
@@ -6,3 +7,5 @@
 void drawPatternBorders(void);
 void writePattern(int32_t currRow, int32_t currPattern);
 void pattTwoHexOut(uint32_t xPos, uint32_t yPos, uint8_t val, uint32_t color);
+
+#endif
--- a/src/ft2_pattern_ed.c
+++ b/src/ft2_pattern_ed.c
@@ -23,7 +23,6 @@
 #include "ft2_bmp.h"
 #include "ft2_structs.h"
 
-pattMark_t pattMark; // globalized
 
 // for pattern marking w/ keyboard
 static int8_t lastChMark;
@@ -42,6 +41,10 @@
 static int32_t lastMouseX, lastMouseY;
 static int32_t last_TimeH, last_TimeM, last_TimeS;
 
+static note_t tmpPattern[MAX_CHANNELS * MAX_PATT_LEN];
+
+pattMark_t pattMark; // globalized
+
 bool allocatePattern(uint16_t pattNum) // for tracker use only, not in loader!
 {
 	const bool audioWasntLocked = !audio.locked;
@@ -2704,8 +2707,7 @@
 	note_t *p = pattern[editor.editPattern];
 	if (p != NULL)
 	{
-		const int32_t length = numRows >> 1;
-		for (int32_t i = 0; i < length; i++)
+		for (int32_t i = 0; i < numRows / 2; i++)
 		{
 			for (int32_t j = 0; j < MAX_CHANNELS; j++)
 				p[(i * MAX_CHANNELS) + j] = p[((i*2) * MAX_CHANNELS) + j];
@@ -2712,13 +2714,13 @@
 		}
 	}
 
-	patternNumRows[editor.editPattern] >>= 1;
+	patternNumRows[editor.editPattern] /= 2;
 	numRows = patternNumRows[editor.editPattern];
 
 	if (song.pattNum == editor.editPattern)
 		song.currNumRows = numRows;
 
-	song.row >>= 1;
+	song.row /= 2;
 	if (song.row >= numRows)
 		song.row = numRows-1;
 
@@ -2734,7 +2736,7 @@
 void expandPattern(void)
 {
 	int16_t numRows = patternNumRows[editor.editPattern];
-	if (numRows > 128)
+	if (numRows > MAX_PATT_LEN/2)
 	{
 		okBox(0, "System message", "Pattern is too long to be expanded.");
 	}
@@ -2744,24 +2746,16 @@
 
 		if (pattern[editor.editPattern] != NULL)
 		{
-			note_t *tmpPtn = (note_t *)malloc((numRows * 2) * TRACK_WIDTH);
-			if (tmpPtn == NULL)
-			{
-				unlockMixerCallback();
-				okBox(0, "System message", "Not enough memory!");
-				return;
-			}
-
+			note_t *p = pattern[editor.editPattern];
+			memcpy(tmpPattern, p, numRows * TRACK_WIDTH);
+			
 			for (int32_t i = 0; i < numRows; i++)
 			{
 				for (int32_t j = 0; j < MAX_CHANNELS; j++)
-					tmpPtn[((i * 2) * MAX_CHANNELS) + j] = pattern[editor.editPattern][(i * MAX_CHANNELS) + j];
+					p[((i * 2) * MAX_CHANNELS) + j] = tmpPattern[(i * MAX_CHANNELS) + j];
 
-				memset(&tmpPtn[((i * 2) + 1) * MAX_CHANNELS], 0, TRACK_WIDTH);
+				memset(&p[((i * 2) + 1) * MAX_CHANNELS], 0, TRACK_WIDTH);
 			}
-
-			free(pattern[editor.editPattern]);
-			pattern[editor.editPattern] = tmpPtn;
 		}
 
 		patternNumRows[editor.editPattern] *= 2;
--- a/src/ft2_pattern_ed.h
+++ b/src/ft2_pattern_ed.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_pattern_ed_h_
+#define _ft2_pattern_ed_h_
 
 #include <stdint.h>
 #include <stdbool.h>
@@ -172,3 +173,5 @@
 void sbSmpBankPos(uint32_t pos);
 void pbToggleLogo(void);
 void pbToggleBadge(void);
+
+#endif
--- a/src/ft2_pushbuttons.h
+++ b/src/ft2_pushbuttons.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_pushbuttons_h_
+#define _ft2_pushbuttons_h_
 
 #include <stdint.h>
 #include <stdbool.h>
@@ -374,3 +375,5 @@
 void handlePushButtonsWhileMouseDown(void);
 bool testPushButtonMouseDown(void);
 int16_t testPushButtonMouseRelease(bool runCallback);
+
+#endif
--- a/src/ft2_radiobuttons.h
+++ b/src/ft2_radiobuttons.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_radiobuttons_h_
+#define _ft2_radiobuttons_h_
 
 #include <stdint.h>
 #include <stdbool.h>
@@ -232,3 +233,5 @@
 void handleRadioButtonsWhileMouseDown(void);
 bool testRadioButtonMouseDown(void);
 void testRadioButtonMouseRelease(void);
+
+#endif
--- a/src/ft2_replayer.h
+++ b/src/ft2_replayer.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_replayer_h_
+#define _ft2_replayer_h_
 
 #include <stdint.h>
 #include <stdbool.h>
@@ -88,9 +89,9 @@
 ** absolutely know what you are doing!
 */
 
-#ifdef _MSC_VER
-#pragma pack(push)
-#pragma pack(1)
+#if defined(_MSC_VER) || defined(__plan9__)
+#pragma pack on
+#pragma pack on
 #endif
 typedef struct xmHdr_t
 {
@@ -204,8 +205,8 @@
 #endif
 syncedChannel_t;
 
-#ifdef _MSC_VER
-#pragma pack(pop)
+#if defined(_MSC_VER) || defined(__plan9__)
+#pragma pack off
 #endif
 
 typedef struct sample_t
@@ -358,3 +359,5 @@
 extern song_t song;
 extern instr_t *instr[128+4];
 extern note_t *pattern[MAX_PATTERNS];
+
+#endif
--- a/src/ft2_sample_ed.h
+++ b/src/ft2_sample_ed.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_sample_ed_h_
+#define _ft2_sample_ed_h_
 
 #include <stdint.h>
 #include "ft2_header.h"
@@ -88,3 +89,5 @@
 void sampleLine(int32_t x1, int32_t x2, int32_t y1, int32_t y2);
 
 extern int32_t smpEd_Rx1, smpEd_Rx2;
+
+#endif
--- a/src/ft2_sample_ed_features.h
+++ b/src/ft2_sample_ed_features.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_sample_ed_features_h_
+#define _ft2_sample_ed_features_h_
 
 #include <stdint.h>
 
@@ -7,3 +8,5 @@
 void pbSampleMix(void);
 void pbSampleVolume(void);
 void handleEchoToolPanic(void);
+
+#endif
--- a/src/ft2_sample_loader.h
+++ b/src/ft2_sample_loader.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_sample_loader_h_
+#define _ft2_sample_loader_h_
 
 #include <stdint.h>
 #include <stdbool.h>
@@ -28,3 +29,5 @@
 
 // file extensions accepted by Disk Op. in sample mode
 extern char *supportedSmpExtensions[];
+
+#endif
--- a/src/ft2_sample_saver.h
+++ b/src/ft2_sample_saver.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_sample_saver_h_
+#define _ft2_sample_saver_h_
 
 #include <stdint.h>
 #include <stdbool.h>
@@ -11,3 +12,5 @@
 };
 
 void saveSample(UNICHAR *filenameU, bool saveAsRange);
+
+#endif
--- a/src/ft2_sampling.h
+++ b/src/ft2_sampling.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_sampling_h_
+#define _ft2_sampling_h_
 
 enum
 {
@@ -10,3 +11,5 @@
 void startSampling(void);
 void stopSampling(void);
 void handleSamplingUpdates(void);
+
+#endif
--- a/src/ft2_scrollbars.h
+++ b/src/ft2_scrollbars.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_scrollbars_h_
+#define _ft2_scrollbars_h_
 
 #include <stdint.h>
 #include <stdbool.h>
@@ -93,3 +94,5 @@
 void testScrollBarMouseRelease(void);
 void handleScrollBarsWhileMouseDown(void);
 void initializeScrollBars(void);
+
+#endif
--- a/src/ft2_structs.h
+++ b/src/ft2_structs.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_structs_h_
+#define _ft2_structs_h_
 
 #include <stdint.h>
 #include <stdbool.h>
@@ -78,3 +79,5 @@
 extern editor_t editor;
 extern ui_t ui;
 extern cursor_t cursor;
+
+#endif
--- a/src/ft2_sysreqs.h
+++ b/src/ft2_sysreqs.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_sysreqs_h_
+#define _ft2_sysreqs_h_
 
 #include <stdint.h>
 #include <stdbool.h>
@@ -31,3 +32,5 @@
 extern void (*loaderMsgBox)(const char *, ...);
 extern int16_t (*loaderSysReq)(int16_t, const char *, const char *);
 // ---------------
+
+#endif
--- a/src/ft2_tables.h
+++ b/src/ft2_tables.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_tables_h_
+#define _ft2_tables_h_
 
 #include <stdint.h>
 #include "ft2_palette.h" // pal16 typedef
@@ -50,3 +51,5 @@
 extern const uint8_t defConfigData[CONFIG_FILE_SIZE];
 
 extern const uint64_t musicTimeTab52[(MAX_BPM-MIN_BPM)+1];
+
+#endif
--- a/src/ft2_textboxes.h
+++ b/src/ft2_textboxes.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_textboxes_h_
+#define _ft2_textboxes_h_
 
 #include <stdint.h>
 #include <stdbool.h>
@@ -76,3 +77,5 @@
 void handleTextEditInputChar(char textChar);
 void handleTextBoxWhileMouseDown(void);
 void freeTextBoxes(void);
+
+#endif
--- a/src/ft2_trim.h
+++ b/src/ft2_trim.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_trim_h_
+#define _ft2_trim_h_
 
 void drawTrimScreen(void);
 void hideTrimScreen(void);
@@ -15,3 +16,5 @@
 void cbTrimSmpsTo8Bit(void);
 void pbTrimCalc(void);
 void pbTrimDoTrim(void);
+
+#endif
--- a/src/ft2_unicode.h
+++ b/src/ft2_unicode.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_unicode_h_
+#define _ft2_unicode_h_
 
 #include <stdbool.h>
 
@@ -50,4 +51,6 @@
 #else
 #define cp437ToUnichar(a) cp437ToUtf8(a)
 #define unicharToCp437(a, b) utf8ToCp437(a, b)
+#endif
+
 #endif
--- a/src/ft2_video.c
+++ b/src/ft2_video.c
@@ -820,18 +820,6 @@
 	uint8_t i;
 	SDL_DisplayMode dm;
 
-	/* Kludge for Raspbarry Pi. Upscaling of 3x or higher makes everything slow as a snail.
-	** This hack unfortunately applies to any ARM based device, but I doubt 3x/4x would run
-	** smooth on any ARM device suitable for the FT2 clone anyway (excluding tablets/phones).
-	*/
-#ifdef __arm__
-	if ((config.windowFlags & WINSIZE_3X) || (config.windowFlags & WINSIZE_4X))
-	{
-		config.windowFlags &= ~(WINSIZE_1X + WINSIZE_2X + WINSIZE_3X + WINSIZE_4X);
-		config.windowFlags |= WINSIZE_AUTO;
-	}
-#endif
-
 	uint8_t oldUpscaleFactor = video.upscaleFactor;
 	if (config.windowFlags & WINSIZE_AUTO)
 	{
@@ -844,8 +832,8 @@
 		{
 			for (i = MAX_UPSCALE_FACTOR; i >= 1; i--)
 			{
-				// slightly bigger than 632x400 because of window title, window borders and taskbar/menu
-				if (dm.w >= 640*i && dm.h >= 450*i)
+				// height test is slightly taller because of window title, window borders and taskbar/menu/dock
+				if (dm.w >= SCREEN_W*i && dm.h >= (SCREEN_H+64)*i)
 				{
 					video.upscaleFactor = i;
 					break;
@@ -854,12 +842,6 @@
 
 			if (i == 0)
 				video.upscaleFactor = 1; // 1x is not going to fit, but use 1x anyways...
-
-			// kludge (read comment above)
-#ifdef __arm__
-			if (video.upscaleFactor > 2)
-				video.upscaleFactor = 2;
-#endif
 		}
 		else
 		{
--- a/src/ft2_video.h
+++ b/src/ft2_video.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_video_h_
+#define _ft2_video_h_
 
 #include <stdint.h>
 #include <stdbool.h>
@@ -75,3 +76,5 @@
 void setWindowSizeFromConfig(bool updateRenderer);
 bool recreateTexture(void);
 void toggleFullscreen(void);
+
+#endif
--- a/src/ft2_wav_renderer.h
+++ b/src/ft2_wav_renderer.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_wav_renderer_h_
+#define _ft2_wav_renderer_h_
 
 #include <stdint.h>
 #include "ft2_header.h"
@@ -33,3 +34,5 @@
 void resetWavRenderer(void);
 void rbWavRenderBitDepth16(void);
 void rbWavRenderBitDepth32(void);
+
+#endif
--- a/src/mixer/ft2_center_mix.h
+++ b/src/mixer/ft2_center_mix.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_center_mix_h_
+#define _ft2_center_mix_h_
 
 #include <stdint.h>
 #include "../ft2_audio.h"
@@ -62,3 +63,5 @@
 void centerMix16bRampNoLoopS16Intrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
 void centerMix16bRampLoopS16Intrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
 void centerMix16bRampBidiLoopS16Intrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples);
+
+#endif
--- a/src/mixer/ft2_mix.h
+++ b/src/mixer/ft2_mix.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_mix_h_
+#define _ft2_mix_h_
 
 #include <stdint.h>
 #include "../ft2_cpu.h"
@@ -16,3 +17,5 @@
 typedef void (*mixFunc)(void *, uint32_t, uint32_t);
 
 extern const mixFunc mixFuncTab[]; // ft2_mix.c
+
+#endif
--- a/src/mixer/ft2_mix_macros.h
+++ b/src/mixer/ft2_mix_macros.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_mix_macros_h_
+#define _ft2_mix_macros_h_
 
 #include "../ft2_audio.h"
 #include "ft2_windowed_sinc.h"
@@ -463,3 +464,5 @@
 	{ \
 		position = (int32_t)(smpPtr - base); \
 	}
+
+#endif
--- a/src/mixer/ft2_silence_mix.h
+++ b/src/mixer/ft2_silence_mix.h
@@ -1,6 +1,9 @@
-#pragma once
+#ifndef _ft2_silence_mix_h_
+#define _ft2_silence_mix_h_
 
 #include <stdint.h>
 #include "../ft2_audio.h"
 
 void silenceMixRoutine(voice_t *v, int32_t numSamples);
+
+#endif
--- a/src/mixer/ft2_windowed_sinc.h
+++ b/src/mixer/ft2_windowed_sinc.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_windowed_sinc_h_
+#define _ft2_windowed_sinc_h_
 
 #include <stdint.h>
 #include <stdbool.h>
@@ -24,3 +25,5 @@
 
 bool calcWindowedSincTables(void);
 void freeWindowedSincTables(void);
+
+#endif
--- a/src/modloaders/ft2_load_digi.c
+++ b/src/modloaders/ft2_load_digi.c
@@ -13,9 +13,9 @@
 #include "../ft2_tables.h"
 #include "../ft2_sysreqs.h"
 
-#ifdef _MSC_VER  // please don't mess with this struct!
-#pragma pack(push)
-#pragma pack(1)
+#if defined(_MSC_VER) || defined(__plan9__)  // please don't mess with this struct!
+#pragma pack on
+#pragma pack on
 #endif
 typedef struct digiHdr_t
 {
@@ -40,8 +40,8 @@
 __attribute__ ((packed))
 #endif
 digiHdr_t;
-#ifdef _MSC_VER
-#pragma pack(pop)
+#if defined(_MSC_VER) || defined(__plan9__)
+#pragma pack off
 #endif
 
 static void readPatternNote(FILE *f, note_t *p);
--- a/src/modloaders/ft2_load_s3m.c
+++ b/src/modloaders/ft2_load_s3m.c
@@ -13,9 +13,9 @@
 #include "../ft2_tables.h"
 #include "../ft2_sysreqs.h"
 
-#ifdef _MSC_VER // please don't mess with these structs!
-#pragma pack(push)
-#pragma pack(1)
+#if defined(_MSC_VER) || defined(__plan9__) // please don't mess with these structs!
+#pragma pack on
+#pragma pack on
 #endif
 typedef struct s3mSmpHdr_t
 {
@@ -47,8 +47,8 @@
 __attribute__ ((packed))
 #endif
 s3mHdr_t;
-#ifdef _MSC_VER
-#pragma pack(pop)
+#if defined(_MSC_VER) || defined(__plan9__)
+#pragma pack off
 #endif
 
 static uint8_t pattBuff[12288];
--- a/src/modloaders/ft2_load_stk.c
+++ b/src/modloaders/ft2_load_stk.c
@@ -13,9 +13,9 @@
 #include "../ft2_tables.h"
 #include "../ft2_sysreqs.h"
 
-#ifdef _MSC_VER  // please don't mess with this struct!
-#pragma pack(push)
-#pragma pack(1)
+#if defined(_MSC_VER) || defined(__plan9__)  // please don't mess with this struct!
+#pragma pack on
+#pragma pack on
 #endif
 typedef struct stkHdr_t
 {
@@ -27,8 +27,8 @@
 __attribute__ ((packed))
 #endif
 stkHdr_t;
-#ifdef _MSC_VER
-#pragma pack(pop)
+#if defined(_MSC_VER) || defined(__plan9__)
+#pragma pack off
 #endif
 
 bool loadSTK(FILE *f, uint32_t filesize)
--- a/src/modloaders/ft2_load_stm.c
+++ b/src/modloaders/ft2_load_stm.c
@@ -13,9 +13,9 @@
 #include "../ft2_tables.h"
 #include "../ft2_sysreqs.h"
 
-#ifdef _MSC_VER // please don't mess with these structs!
-#pragma pack(push)
-#pragma pack(1)
+#if defined(_MSC_VER) || defined(__plan9__) // please don't mess with these structs!
+#pragma pack on
+#pragma pack on
 #endif
 typedef struct stmSmpHdr_t
 {
@@ -45,8 +45,8 @@
 __attribute__ ((packed))
 #endif
 stmHdr_t;
-#ifdef _MSC_VER
-#pragma pack(pop)
+#if defined(_MSC_VER) || defined(__plan9__)
+#pragma pack off
 #endif
 
 static const uint8_t stmEfx[16] = { 0, 0, 11, 0, 10, 2, 1, 3, 4, 7, 0, 5, 6, 0, 0, 0 };
--- a/src/scopes/ft2_scope_macros.h
+++ b/src/scopes/ft2_scope_macros.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_scope_macros_h_
+#define _ft2_scope_macros_h_
 
 #include <stdint.h>
 #include "ft2_scopes.h"
@@ -244,3 +245,5 @@
 		else \
 			position = sampleEnd - 1; \
 	}
+
+#endif
--- a/src/scopes/ft2_scopedraw.h
+++ b/src/scopes/ft2_scopedraw.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_scopedraw_h_
+#define _ft2_scopedraw_h_
 
 #include <stdint.h>
 #include "ft2_scopes.h"
@@ -6,3 +7,5 @@
 typedef void (*scopeDrawRoutine)(const scope_t *, uint32_t, uint32_t, uint32_t);
 
 extern const scopeDrawRoutine scopeDrawRoutineTable[12]; // ft2_scopedraw.c
+
+#endif
--- a/src/scopes/ft2_scopes.h
+++ b/src/scopes/ft2_scopes.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef _ft2_scopes_h_
+#define _ft2_scopes_h_
 
 #include <stdint.h>
 #include <stdbool.h>
@@ -47,3 +48,5 @@
 } lastChInstr_t;
 
 extern lastChInstr_t lastChInstr[MAX_CHANNELS];
+
+#endif
--- a/vs2019_project/ft2-clone/sdl/include/SDL2/SDL_atomic.h
+++ b/vs2019_project/ft2-clone/sdl/include/SDL2/SDL_atomic.h
@@ -249,9 +249,8 @@
 #elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_ARM64))
     #define SDL_CPUPauseInstruction() __yield()
 #elif defined(__WATCOMC__) && defined(__386__)
-    /* watcom assembler rejects PAUSE if CPU < i686, and it refuses REP NOP as an invalid combination. Hardcode the bytes.  */
     extern __inline void SDL_CPUPauseInstruction(void);
-    #pragma aux SDL_CPUPauseInstruction = "db 0f3h,90h"
+    #pragma aux SDL_CPUPauseInstruction = ".686p" ".xmm2" "pause"
 #else
     #define SDL_CPUPauseInstruction()
 #endif
--- a/vs2019_project/ft2-clone/sdl/include/SDL2/SDL_audio.h
+++ b/vs2019_project/ft2-clone/sdl/include/SDL2/SDL_audio.h
@@ -169,13 +169,13 @@
  *  The calculated values in this structure are calculated by SDL_OpenAudio().
  *
  *  For multi-channel audio, the default SDL channel mapping is:
- *  2:  FL FR                       (stereo)
- *  3:  FL FR LFE                   (2.1 surround)
- *  4:  FL FR BL BR                 (quad)
- *  5:  FL FR LFE BL BR             (4.1 surround)
- *  6:  FL FR FC LFE SL SR          (5.1 surround - last two can also be BL BR)
- *  7:  FL FR FC LFE BC SL SR       (6.1 surround)
- *  8:  FL FR FC LFE BL BR SL SR    (7.1 surround)
+ *  2:  FL  FR                          (stereo)
+ *  3:  FL  FR LFE                      (2.1 surround)
+ *  4:  FL  FR  BL  BR                  (quad)
+ *  5:  FL  FR LFE  BL  BR              (4.1 surround)
+ *  6:  FL  FR  FC LFE  SL  SR          (5.1 surround - last two can also be BL BR)
+ *  7:  FL  FR  FC LFE  BC  SL  SR      (6.1 surround)
+ *  8:  FL  FR  FC LFE  BL  BR  SL  SR  (7.1 surround)
  */
 typedef struct SDL_AudioSpec
 {
--- a/vs2019_project/ft2-clone/sdl/include/SDL2/SDL_blendmode.h
+++ b/vs2019_project/ft2-clone/sdl/include/SDL2/SDL_blendmode.h
@@ -52,7 +52,7 @@
                                               dstA = dstA */
     SDL_BLENDMODE_MUL = 0x00000008,      /**< color multiply
                                               dstRGB = (srcRGB * dstRGB) + (dstRGB * (1-srcA))
-                                              dstA = (srcA * dstA) + (dstA * (1-srcA)) */
+                                              dstA = dstA */
     SDL_BLENDMODE_INVALID = 0x7FFFFFFF
 
     /* Additional custom blend modes can be returned by SDL_ComposeCustomBlendMode() */
--- a/vs2019_project/ft2-clone/sdl/include/SDL2/SDL_endian.h
+++ b/vs2019_project/ft2-clone/sdl/include/SDL2/SDL_endian.h
@@ -140,7 +140,7 @@
 
 #if HAS_BUILTIN_BSWAP16
 #define SDL_Swap16(x) __builtin_bswap16(x)
-#elif defined(_MSC_VER) && (_MSC_VER >= 1400)
+#elif (defined(_MSC_VER) && (_MSC_VER >= 1400)) && !defined(__ICL)
 #pragma intrinsic(_byteswap_ushort)
 #define SDL_Swap16(x) _byteswap_ushort(x)
 #elif defined(__i386__) && !HAS_BROKEN_BSWAP
@@ -189,7 +189,7 @@
 
 #if HAS_BUILTIN_BSWAP32
 #define SDL_Swap32(x) __builtin_bswap32(x)
-#elif defined(_MSC_VER) && (_MSC_VER >= 1400)
+#elif (defined(_MSC_VER) && (_MSC_VER >= 1400)) && !defined(__ICL)
 #pragma intrinsic(_byteswap_ulong)
 #define SDL_Swap32(x) _byteswap_ulong(x)
 #elif defined(__i386__) && !HAS_BROKEN_BSWAP
@@ -241,7 +241,7 @@
 
 #if HAS_BUILTIN_BSWAP64
 #define SDL_Swap64(x) __builtin_bswap64(x)
-#elif defined(_MSC_VER) && (_MSC_VER >= 1400)
+#elif (defined(_MSC_VER) && (_MSC_VER >= 1400)) && !defined(__ICL)
 #pragma intrinsic(_byteswap_uint64)
 #define SDL_Swap64(x) _byteswap_uint64(x)
 #elif defined(__i386__) && !HAS_BROKEN_BSWAP
--- a/vs2019_project/ft2-clone/sdl/include/SDL2/SDL_gamecontroller.h
+++ b/vs2019_project/ft2-clone/sdl/include/SDL2/SDL_gamecontroller.h
@@ -724,10 +724,10 @@
     SDL_CONTROLLER_BUTTON_DPAD_LEFT,
     SDL_CONTROLLER_BUTTON_DPAD_RIGHT,
     SDL_CONTROLLER_BUTTON_MISC1,    /* Xbox Series X share button, PS5 microphone button, Nintendo Switch Pro capture button, Amazon Luna microphone button */
-    SDL_CONTROLLER_BUTTON_PADDLE1,  /* Xbox Elite paddle P1 */
-    SDL_CONTROLLER_BUTTON_PADDLE2,  /* Xbox Elite paddle P3 */
-    SDL_CONTROLLER_BUTTON_PADDLE3,  /* Xbox Elite paddle P2 */
-    SDL_CONTROLLER_BUTTON_PADDLE4,  /* Xbox Elite paddle P4 */
+    SDL_CONTROLLER_BUTTON_PADDLE1,  /* Xbox Elite paddle P1 (upper left, facing the back) */
+    SDL_CONTROLLER_BUTTON_PADDLE2,  /* Xbox Elite paddle P3 (upper right, facing the back) */
+    SDL_CONTROLLER_BUTTON_PADDLE3,  /* Xbox Elite paddle P2 (lower left, facing the back) */
+    SDL_CONTROLLER_BUTTON_PADDLE4,  /* Xbox Elite paddle P4 (lower right, facing the back) */
     SDL_CONTROLLER_BUTTON_TOUCHPAD, /* PS4/PS5 touchpad button */
     SDL_CONTROLLER_BUTTON_MAX
 } SDL_GameControllerButton;
--- a/vs2019_project/ft2-clone/sdl/include/SDL2/SDL_hints.h
+++ b/vs2019_project/ft2-clone/sdl/include/SDL2/SDL_hints.h
@@ -92,7 +92,7 @@
  * By default this hint is not set and the APK expansion files are not searched.
  */
 #define SDL_HINT_ANDROID_APK_EXPANSION_MAIN_FILE_VERSION "SDL_ANDROID_APK_EXPANSION_MAIN_FILE_VERSION"
- 
+
 /**
  * \brief Android APK expansion patch file version. Should be a string number like "1", "2" etc.
  *
@@ -132,13 +132,13 @@
  * \brief A variable to control whether we trap the Android back button to handle it manually.
  *        This is necessary for the right mouse button to work on some Android devices, or
  *        to be able to trap the back button for use in your code reliably.  If set to true,
- *        the back button will show up as an SDL_KEYDOWN / SDL_KEYUP pair with a keycode of 
+ *        the back button will show up as an SDL_KEYDOWN / SDL_KEYUP pair with a keycode of
  *        SDL_SCANCODE_AC_BACK.
  *
  * The variable can be set to the following values:
  *   "0"       - Back button will be handled as usual for system. (default)
  *   "1"       - Back button will be trapped, allowing you to handle the key press
- *               manually.  (This will also let right mouse click work on systems 
+ *               manually.  (This will also let right mouse click work on systems
  *               where the right mouse button functions as back.)
  *
  * The value of this hint is used at runtime, so it can be changed at any time.
@@ -147,7 +147,7 @@
 
 /**
  *  \brief Specify an application name.
- * 
+ *
  * This hint lets you specify the application name sent to the OS when
  * required. For example, this will often appear in volume control applets for
  * audio streams, and in lists of applications which are inhibiting the
@@ -378,6 +378,17 @@
 #define SDL_HINT_EMSCRIPTEN_KEYBOARD_ELEMENT   "SDL_EMSCRIPTEN_KEYBOARD_ELEMENT"
 
 /**
+ *  \brief  A variable that controls whether the on-screen keyboard should be shown when text input is active
+ *
+ *  The variable can be set to the following values:
+ *    "0"       - Do not show the on-screen keyboard
+ *    "1"       - Show the on-screen keyboard
+ *
+ *  The default value is "1". This hint must be set before text input is activated.
+ */
+#define SDL_HINT_ENABLE_SCREEN_KEYBOARD "SDL_ENABLE_SCREEN_KEYBOARD"
+
+/**
  *  \brief  A variable that controls whether Steam Controllers should be exposed using the SDL joystick and game controller APIs
  *
  *  The variable can be set to the following values:
@@ -507,7 +518,7 @@
 
 /**
  *  \brief  If set, game controller face buttons report their values according to their labels instead of their positional layout.
- * 
+ *
  *  For example, on Nintendo Switch controllers, normally you'd get:
  *
  *      (Y)
@@ -569,9 +580,9 @@
  *
  * The variable can be set to the following values:
  *   "0"       - SDL_TEXTEDITING events are sent, and it is the application's
- *               responsibility to render the text from these events and 
+ *               responsibility to render the text from these events and
  *               differentiate it somehow from committed text. (default)
- *   "1"       - If supported by the IME then SDL_TEXTEDITING events are not sent, 
+ *   "1"       - If supported by the IME then SDL_TEXTEDITING events are not sent,
  *               and text that is being composed will be rendered in its own UI.
  */
 #define SDL_HINT_IME_INTERNAL_EDITING "SDL_IME_INTERNAL_EDITING"
@@ -1310,6 +1321,8 @@
  *
  *  This variable can be one of the following values:
  *    "primary" (default), "portrait", "landscape", "inverted-portrait", "inverted-landscape"
+ *
+ *  Since SDL 2.0.22 this variable accepts a comma-separated list of values above.
  */
 #define SDL_HINT_QTWAYLAND_CONTENT_ORIENTATION "SDL_QTWAYLAND_CONTENT_ORIENTATION"
 
@@ -1495,7 +1508,7 @@
  * disabled. You should use a string that describes what your program is doing
  * (and, therefore, why the screensaver is disabled).  For example, "Playing a
  * game" or "Watching a video".
- * 
+ *
  * Setting this to "" or leaving it unset will have SDL use a reasonable
  * default: "Playing a game" or something similar.
  *
@@ -1509,13 +1522,13 @@
  *  On some platforms, like Linux, a realtime priority thread may be subject to restrictions
  *  that require special handling by the application. This hint exists to let SDL know that
  *  the app is prepared to handle said restrictions.
- * 
+ *
  *  On Linux, SDL will apply the following configuration to any thread that becomes realtime:
  *   * The SCHED_RESET_ON_FORK bit will be set on the scheduling policy,
  *   * An RLIMIT_RTTIME budget will be configured to the rtkit specified limit.
  *     * Exceeding this limit will result in the kernel sending SIGKILL to the app,
  *     * Refer to the man pages for more information.
- * 
+ *
  *  This variable can be set to the following values:
  *    "0"       - default platform specific behaviour
  *    "1"       - Force SDL_THREAD_PRIORITY_TIME_CRITICAL to a realtime scheduling policy
@@ -1603,7 +1616,7 @@
 #define SDL_HINT_TV_REMOTE_AS_JOYSTICK "SDL_TV_REMOTE_AS_JOYSTICK"
 
 /**
- *  \brief  A variable controlling whether the screensaver is enabled. 
+ *  \brief  A variable controlling whether the screensaver is enabled.
  *
  *  This variable can be set to the following values:
  *    "0"       - Disable screensaver
@@ -1616,7 +1629,7 @@
 /**
  * \brief Tell the video driver that we only want a double buffer.
  *
- * By default, most lowlevel 2D APIs will use a triple buffer scheme that 
+ * By default, most lowlevel 2D APIs will use a triple buffer scheme that
  * wastes no CPU time on waiting for vsync after issuing a flip, but
  * introduces a frame of latency. On the other hand, using a double buffer
  * scheme instead is recommended for cases where low latency is an important
@@ -1747,9 +1760,9 @@
 
 /**
 *  \brief  A variable that is the address of another SDL_Window* (as a hex string formatted with "%p").
-*  
+*
 *  If this hint is set before SDL_CreateWindowFrom() and the SDL_Window* it is set to has
-*  SDL_WINDOW_OPENGL set (and running on WGL only, currently), then two things will occur on the newly 
+*  SDL_WINDOW_OPENGL set (and running on WGL only, currently), then two things will occur on the newly
 *  created SDL_Window:
 *
 *  1. Its pixel format will be set to the same pixel format as this SDL_Window.  This is
@@ -1815,13 +1828,13 @@
 
 /**
  * \brief A variable controlling whether the X11 _NET_WM_BYPASS_COMPOSITOR hint should be used.
- * 
+ *
  * This variable can be set to the following values:
  * "0" - Disable _NET_WM_BYPASS_COMPOSITOR
  * "1" - Enable _NET_WM_BYPASS_COMPOSITOR
- * 
+ *
  * By default SDL will use _NET_WM_BYPASS_COMPOSITOR
- * 
+ *
  */
 #define SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR "SDL_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR"
 
@@ -1955,9 +1968,31 @@
 #define SDL_HINT_WINDOWS_DISABLE_THREAD_NAMING "SDL_WINDOWS_DISABLE_THREAD_NAMING"
 
 /**
- *  \brief  A variable controlling whether the windows message loop is processed by SDL 
+ *  \brief Controls whether menus can be opened with their keyboard shortcut (Alt+mnemonic).
  *
+ *  If the mnemonics are enabled, then menus can be opened by pressing the Alt
+ *  key and the corresponding mnemonic (for example, Alt+F opens the File menu).
+ *  However, in case an invalid mnemonic is pressed, Windows makes an audible
+ *  beep to convey that nothing happened. This is true even if the window has
+ *  no menu at all!
+ *
+ *  Because most SDL applications don't have menus, and some want to use the Alt
+ *  key for other purposes, SDL disables mnemonics (and the beeping) by default.
+ *
+ *  Note: This also affects keyboard events: with mnemonics enabled, when a
+ *  menu is opened from the keyboard, you will not receive a KEYUP event for
+ *  the mnemonic key, and *might* not receive one for Alt.
+ *
  *  This variable can be set to the following values:
+ *    "0"       - Alt+mnemonic does nothing, no beeping. (default)
+ *    "1"       - Alt+mnemonic opens menus, invalid mnemonics produce a beep.
+ */
+#define SDL_HINT_WINDOWS_ENABLE_MENU_MNEMONICS "SDL_WINDOWS_ENABLE_MENU_MNEMONICS"
+
+/**
+ *  \brief  A variable controlling whether the windows message loop is processed by SDL
+ *
+ *  This variable can be set to the following values:
  *    "0"       - The window message loop is not run
  *    "1"       - The window message loop is processed in SDL_PumpEvents()
  *
@@ -1996,7 +2031,7 @@
 #define SDL_HINT_WINDOWS_FORCE_SEMAPHORE_KERNEL "SDL_WINDOWS_FORCE_SEMAPHORE_KERNEL"
 
 /**
- * \brief A variable to specify custom icon resource id from RC file on Windows platform 
+ * \brief A variable to specify custom icon resource id from RC file on Windows platform
  */
 #define SDL_HINT_WINDOWS_INTRESOURCE_ICON       "SDL_WINDOWS_INTRESOURCE_ICON"
 #define SDL_HINT_WINDOWS_INTRESOURCE_ICON_SMALL "SDL_WINDOWS_INTRESOURCE_ICON_SMALL"
@@ -2035,16 +2070,16 @@
  *
  *  This hint must be set before initializing the video subsystem.
  *
- *  The main purpose of declaring DPI awareness is to disable OS bitmap scaling of SDL windows on monitors with 
+ *  The main purpose of declaring DPI awareness is to disable OS bitmap scaling of SDL windows on monitors with
  *  a DPI scale factor.
- * 
+ *
  *  This hint is equivalent to requesting DPI awareness via external means (e.g. calling SetProcessDpiAwarenessContext)
  *  and does not cause SDL to use a virtualized coordinate system, so it will generally give you 1 SDL coordinate = 1 pixel
  *  even on high-DPI displays.
- * 
+ *
  *  For more information, see:
  *  https://docs.microsoft.com/en-us/windows/win32/hidpi/high-dpi-desktop-application-development-on-windows
- * 
+ *
  *  This variable can be set to the following values:
  *    ""             - Do not change the DPI awareness (default).
  *    "unaware"      - Declare the process as DPI unaware. (Windows 8.1 and later).
@@ -2062,16 +2097,16 @@
 
 /**
  * \brief Uses DPI-scaled points as the SDL coordinate system on Windows.
- * 
+ *
  *  This changes the SDL coordinate system units to be DPI-scaled points, rather than pixels everywhere.
  *  This means windows will be appropriately sized, even when created on high-DPI displays with scaling.
- * 
+ *
  *  e.g. requesting a 640x480 window from SDL, on a display with 125% scaling in Windows display settings,
  *  will create a window with an 800x600 client area (in pixels).
  *
  *  Setting this to "1" implicitly requests process DPI awareness (setting SDL_WINDOWS_DPI_AWARENESS is unnecessary),
  *  and forces SDL_WINDOW_ALLOW_HIGHDPI on all windows.
- * 
+ *
  *  This variable can be set to the following values:
  *    "0"       - SDL coordinates equal Windows coordinates. No automatic window resizing when dragging
  *                between monitors with different scale factors (unless this is performed by
@@ -2082,7 +2117,7 @@
 #define SDL_HINT_WINDOWS_DPI_SCALING "SDL_WINDOWS_DPI_SCALING"
 
 /**
- *  \brief  A variable controlling whether the window frame and title bar are interactive when the cursor is hidden 
+ *  \brief  A variable controlling whether the window frame and title bar are interactive when the cursor is hidden
  *
  *  This variable can be set to the following values:
  *    "0"       - The window frame is not interactive when the cursor is hidden (no move, resize, etc)
@@ -2093,7 +2128,7 @@
 #define SDL_HINT_WINDOW_FRAME_USABLE_WHILE_CURSOR_HIDDEN    "SDL_WINDOW_FRAME_USABLE_WHILE_CURSOR_HIDDEN"
 
 /**
-*  \brief  A variable controlling whether the window is activated when the SDL_ShowWindow function is called 
+*  \brief  A variable controlling whether the window is activated when the SDL_ShowWindow function is called
 *
 *  This variable can be set to the following values:
 *    "0"       - The window is activated when the SDL_ShowWindow function is called
--- a/vs2019_project/ft2-clone/sdl/include/SDL2/SDL_joystick.h
+++ b/vs2019_project/ft2-clone/sdl/include/SDL2/SDL_joystick.h
@@ -44,6 +44,7 @@
 #include "SDL_stdinc.h"
 #include "SDL_error.h"
 #include "SDL_guid.h"
+#include "SDL_mutex.h"
 
 #include "begin_code.h"
 /* Set up for C function definitions, even when using C++ */
@@ -66,6 +67,9 @@
 /**
  * The joystick structure used to identify an SDL joystick
  */
+#ifdef SDL_THREAD_SAFETY_ANALYSIS
+extern SDL_mutex *SDL_joystick_lock;
+#endif
 struct _SDL_Joystick;
 typedef struct _SDL_Joystick SDL_Joystick;
 
@@ -131,7 +135,7 @@
  *
  * \since This function is available since SDL 2.0.7.
  */
-extern DECLSPEC void SDLCALL SDL_LockJoysticks(void);
+extern DECLSPEC void SDLCALL SDL_LockJoysticks(void) SDL_ACQUIRE(SDL_joystick_lock);
 
 
 /**
@@ -146,7 +150,7 @@
  *
  * \since This function is available since SDL 2.0.7.
  */
-extern DECLSPEC void SDLCALL SDL_UnlockJoysticks(void);
+extern DECLSPEC void SDLCALL SDL_UnlockJoysticks(void) SDL_RELEASE(SDL_joystick_lock);
 
 /**
  * Count the number of joysticks attached to the system.
@@ -284,13 +288,12 @@
 /**
  * Get the instance ID of a joystick.
  *
- * This can be called before any joysticks are opened. If the index is out of
- * range, this function will return -1.
+ * This can be called before any joysticks are opened.
  *
  * \param device_index the index of the joystick to query (the N'th joystick
  *                     on the system
  * \returns the instance id of the selected joystick. If called on an invalid
- *          index, this function returns zero
+ *          index, this function returns -1.
  *
  * \since This function is available since SDL 2.0.6.
  */
--- a/vs2019_project/ft2-clone/sdl/include/SDL2/SDL_keycode.h
+++ b/vs2019_project/ft2-clone/sdl/include/SDL2/SDL_keycode.h
@@ -40,7 +40,7 @@
  *  an SDLK_* constant for those keys that do not generate characters.
  *
  *  A special exception is the number keys at the top of the keyboard which
- *  always map to SDLK_0...SDLK_9, regardless of layout.
+ *  map to SDLK_0...SDLK_9 on AZERTY layouts.
  */
 typedef Sint32 SDL_Keycode;
 
--- a/vs2019_project/ft2-clone/sdl/include/SDL2/SDL_main.h
+++ b/vs2019_project/ft2-clone/sdl/include/SDL2/SDL_main.h
@@ -263,6 +263,13 @@
  */
 extern DECLSPEC int SDLCALL SDL_GDKRunApp(SDL_main_func mainFunction, void *reserved);
 
+/**
+ * Callback from the application to let the suspend continue.
+ *
+ * \since This function is available since SDL 2.28.0.
+ */
+extern DECLSPEC void SDLCALL SDL_GDKSuspendComplete(void);
+
 #endif /* __GDK__ */
 
 #ifdef __cplusplus
--- a/vs2019_project/ft2-clone/sdl/include/SDL2/SDL_mouse.h
+++ b/vs2019_project/ft2-clone/sdl/include/SDL2/SDL_mouse.h
@@ -198,14 +198,10 @@
 /**
  * Set relative mouse mode.
  *
- * While the mouse is in relative mode, the cursor is hidden, and the driver
- * will try to report continuous motion in the current window. Only relative
- * motion events will be delivered, the mouse position will not change.
+ * While the mouse is in relative mode, the cursor is hidden, the mouse
+ * position is constrained to the window, and SDL will report continuous
+ * relative mouse motion even if the mouse is at the edge of the window.
  *
- * Note that this function will not be able to provide continuous relative
- * motion when used over Microsoft Remote Desktop, instead motion is limited
- * to the bounds of the screen.
- *
  * This function will flush any pending mouse motion.
  *
  * \param enabled SDL_TRUE to enable relative mode, SDL_FALSE to disable.
@@ -388,6 +384,9 @@
 
 /**
  * Get the default cursor.
+ *
+ * You do not have to call SDL_FreeCursor() on the return value, but it is
+ * safe to do so.
  *
  * \returns the default cursor on success or NULL on failure.
  *
--- a/vs2019_project/ft2-clone/sdl/include/SDL2/SDL_mutex.h
+++ b/vs2019_project/ft2-clone/sdl/include/SDL2/SDL_mutex.h
@@ -31,6 +31,80 @@
 #include "SDL_stdinc.h"
 #include "SDL_error.h"
 
+/******************************************************************************/
+/* Enable thread safety attributes only with clang.
+ * The attributes can be safely erased when compiling with other compilers.
+ */
+#if defined(SDL_THREAD_SAFETY_ANALYSIS) && \
+    defined(__clang__) && (!defined(SWIG))
+#define SDL_THREAD_ANNOTATION_ATTRIBUTE__(x)   __attribute__((x))
+#else
+#define SDL_THREAD_ANNOTATION_ATTRIBUTE__(x)   /* no-op */
+#endif
+
+#define SDL_CAPABILITY(x) \
+  SDL_THREAD_ANNOTATION_ATTRIBUTE__(capability(x))
+
+#define SDL_SCOPED_CAPABILITY \
+  SDL_THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable)
+
+#define SDL_GUARDED_BY(x) \
+  SDL_THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x))
+
+#define SDL_PT_GUARDED_BY(x) \
+  SDL_THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_by(x))
+
+#define SDL_ACQUIRED_BEFORE(x) \
+  SDL_THREAD_ANNOTATION_ATTRIBUTE__(acquired_before(x))
+
+#define SDL_ACQUIRED_AFTER(x) \
+  SDL_THREAD_ANNOTATION_ATTRIBUTE__(acquired_after(x))
+
+#define SDL_REQUIRES(x) \
+  SDL_THREAD_ANNOTATION_ATTRIBUTE__(requires_capability(x))
+
+#define SDL_REQUIRES_SHARED(x) \
+  SDL_THREAD_ANNOTATION_ATTRIBUTE__(requires_shared_capability(x))
+
+#define SDL_ACQUIRE(x) \
+  SDL_THREAD_ANNOTATION_ATTRIBUTE__(acquire_capability(x))
+
+#define SDL_ACQUIRE_SHARED(x) \
+  SDL_THREAD_ANNOTATION_ATTRIBUTE__(acquire_shared_capability(x))
+
+#define SDL_RELEASE(x) \
+  SDL_THREAD_ANNOTATION_ATTRIBUTE__(release_capability(x))
+
+#define SDL_RELEASE_SHARED(x) \
+  SDL_THREAD_ANNOTATION_ATTRIBUTE__(release_shared_capability(x))
+
+#define SDL_RELEASE_GENERIC(x) \
+  SDL_THREAD_ANNOTATION_ATTRIBUTE__(release_generic_capability(x))
+
+#define SDL_TRY_ACQUIRE(x, y) \
+  SDL_THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_capability(x, y))
+
+#define SDL_TRY_ACQUIRE_SHARED(x, y) \
+  SDL_THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_shared_capability(x, y))
+
+#define SDL_EXCLUDES(x) \
+  SDL_THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(x))
+
+#define SDL_ASSERT_CAPABILITY(x) \
+  SDL_THREAD_ANNOTATION_ATTRIBUTE__(assert_capability(x))
+
+#define SDL_ASSERT_SHARED_CAPABILITY(x) \
+  SDL_THREAD_ANNOTATION_ATTRIBUTE__(assert_shared_capability(x))
+
+#define SDL_RETURN_CAPABILITY(x) \
+  SDL_THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x))
+
+#define SDL_NO_THREAD_SAFETY_ANALYSIS \
+  SDL_THREAD_ANNOTATION_ATTRIBUTE__(no_thread_safety_analysis)
+
+/******************************************************************************/
+
+
 #include "begin_code.h"
 /* Set up for C function definitions, even when using C++ */
 #ifdef __cplusplus
@@ -96,7 +170,7 @@
  *
  * \since This function is available since SDL 2.0.0.
  */
-extern DECLSPEC int SDLCALL SDL_LockMutex(SDL_mutex * mutex);
+extern DECLSPEC int SDLCALL SDL_LockMutex(SDL_mutex * mutex) SDL_ACQUIRE(mutex);
 #define SDL_mutexP(m)   SDL_LockMutex(m)
 
 /**
@@ -119,7 +193,7 @@
  * \sa SDL_LockMutex
  * \sa SDL_UnlockMutex
  */
-extern DECLSPEC int SDLCALL SDL_TryLockMutex(SDL_mutex * mutex);
+extern DECLSPEC int SDLCALL SDL_TryLockMutex(SDL_mutex * mutex) SDL_TRY_ACQUIRE(0, mutex);
 
 /**
  * Unlock the mutex.
@@ -138,7 +212,7 @@
  *
  * \since This function is available since SDL 2.0.0.
  */
-extern DECLSPEC int SDLCALL SDL_UnlockMutex(SDL_mutex * mutex);
+extern DECLSPEC int SDLCALL SDL_UnlockMutex(SDL_mutex * mutex) SDL_RELEASE(mutex);
 #define SDL_mutexV(m)   SDL_UnlockMutex(m)
 
 /**
@@ -276,7 +350,7 @@
  * successful it will atomically decrement the semaphore value.
  *
  * \param sem the semaphore to wait on
- * \param ms the length of the timeout, in milliseconds
+ * \param timeout the length of the timeout, in milliseconds
  * \returns 0 if the wait succeeds, `SDL_MUTEX_TIMEDOUT` if the wait does not
  *          succeed in the allotted time, or a negative error code on failure;
  *          call SDL_GetError() for more information.
@@ -290,7 +364,7 @@
  * \sa SDL_SemValue
  * \sa SDL_SemWait
  */
-extern DECLSPEC int SDLCALL SDL_SemWaitTimeout(SDL_sem * sem, Uint32 ms);
+extern DECLSPEC int SDLCALL SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout);
 
 /**
  * Atomically increment a semaphore's value and wake waiting threads.
--- a/vs2019_project/ft2-clone/sdl/include/SDL2/SDL_opengl_glext.h
+++ b/vs2019_project/ft2-clone/sdl/include/SDL2/SDL_opengl_glext.h
@@ -1,4 +1,8 @@
-#ifndef __gl_glext_h_
+/* SDL modified the include guard to be compatible with Mesa and Apple include guards:
+ * - Mesa uses: __gl_glext_h_
+ * - Apple uses: __glext_h_  */
+#if !defined(__glext_h_) && !defined(__gl_glext_h_)
+#define __glext_h_ 1
 #define __gl_glext_h_ 1
 
 #ifdef __cplusplus
--- a/vs2019_project/ft2-clone/sdl/include/SDL2/SDL_power.h
+++ b/vs2019_project/ft2-clone/sdl/include/SDL2/SDL_power.h
@@ -48,7 +48,6 @@
     SDL_POWERSTATE_CHARGED       /**< Plugged in, battery charged */
 } SDL_PowerState;
 
-
 /**
  * Get the current power supply details.
  *
@@ -65,17 +64,17 @@
  * It's possible a platform can only report battery percentage or time left
  * but not both.
  *
- * \param secs seconds of battery life left, you can pass a NULL here if you
- *             don't care, will return -1 if we can't determine a value, or
- *             we're not running on a battery
- * \param pct percentage of battery life left, between 0 and 100, you can pass
- *            a NULL here if you don't care, will return -1 if we can't
- *            determine a value, or we're not running on a battery
+ * \param seconds seconds of battery life left, you can pass a NULL here if
+ *                you don't care, will return -1 if we can't determine a
+ *                value, or we're not running on a battery
+ * \param percent percentage of battery life left, between 0 and 100, you can
+ *                pass a NULL here if you don't care, will return -1 if we
+ *                can't determine a value, or we're not running on a battery
  * \returns an SDL_PowerState enum representing the current battery state.
  *
  * \since This function is available since SDL 2.0.0.
  */
-extern DECLSPEC SDL_PowerState SDLCALL SDL_GetPowerInfo(int *secs, int *pct);
+extern DECLSPEC SDL_PowerState SDLCALL SDL_GetPowerInfo(int *seconds, int *percent);
 
 /* Ends C function definitions when using C++ */
 #ifdef __cplusplus
--- a/vs2019_project/ft2-clone/sdl/include/SDL2/SDL_render.h
+++ b/vs2019_project/ft2-clone/sdl/include/SDL2/SDL_render.h
@@ -1731,6 +1731,11 @@
  *
  * \param renderer the rendering context
  *
+ * \threadsafety You may only call this function on the main thread. If this
+ *               happens to work on a background thread on any given platform
+ *               or backend, it's purely by luck and you should not rely on it
+ *               to work next time.
+ *
  * \since This function is available since SDL 2.0.0.
  *
  * \sa SDL_RenderClear
--- a/vs2019_project/ft2-clone/sdl/include/SDL2/SDL_revision.h
+++ b/vs2019_project/ft2-clone/sdl/include/SDL2/SDL_revision.h
@@ -1,7 +1,7 @@
 /* Generated by updaterev.sh, do not edit */
 #ifdef SDL_VENDOR_INFO
-#define SDL_REVISION "SDL-release-2.26.5-0-gac13ca9ab (" SDL_VENDOR_INFO ")"
+#define SDL_REVISION "SDL-release-2.28.0-0-gffa78e6be (" SDL_VENDOR_INFO ")"
 #else
-#define SDL_REVISION "SDL-release-2.26.5-0-gac13ca9ab"
+#define SDL_REVISION "SDL-release-2.28.0-0-gffa78e6be"
 #endif
 #define SDL_REVISION_NUMBER 0
--- a/vs2019_project/ft2-clone/sdl/include/SDL2/SDL_sensor.h
+++ b/vs2019_project/ft2-clone/sdl/include/SDL2/SDL_sensor.h
@@ -84,7 +84,7 @@
  * The accelerometer returns the current acceleration in SI meters per
  * second squared. This measurement includes the force of gravity, so
  * a device at rest will have an value of SDL_STANDARD_GRAVITY away
- * from the center of the earth.
+ * from the center of the earth, which is a positive Y value.
  *
  * values[0]: Acceleration on the x axis
  * values[1]: Acceleration on the y axis
--- a/vs2019_project/ft2-clone/sdl/include/SDL2/SDL_stdinc.h
+++ b/vs2019_project/ft2-clone/sdl/include/SDL2/SDL_stdinc.h
@@ -30,12 +30,6 @@
 
 #include "SDL_config.h"
 
-#ifdef __APPLE__
-#ifndef _DARWIN_C_SOURCE
-#define _DARWIN_C_SOURCE 1 /* for memset_pattern4() */
-#endif
-#endif
-
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
 #endif
@@ -85,7 +79,9 @@
    Visual Studio.  See http://msdn.microsoft.com/en-us/library/4hwaceh6.aspx
    for more information.
 */
-#  define _USE_MATH_DEFINES
+#  ifndef _USE_MATH_DEFINES
+#    define _USE_MATH_DEFINES
+#  endif
 # endif
 # include <math.h>
 #endif
@@ -248,7 +244,7 @@
 #ifdef FLT_EPSILON
 #define SDL_FLT_EPSILON FLT_EPSILON
 #else
-#define SDL_FLT_EPSILON 0.0000000001f /* 8bitbubsy: had to modify this for VC... */
+#define SDL_FLT_EPSILON 0.0000001f /* 8bitbubsy: had to modify this for MSVC... */
 #endif
 
 /* @} *//* Floating-point constants */
@@ -528,9 +524,7 @@
 /* Note that memset() is a byte assignment and this is a 32-bit assignment, so they're not directly equivalent. */
 SDL_FORCE_INLINE void SDL_memset4(void *dst, Uint32 val, size_t dwords)
 {
-#ifdef __APPLE__
-    memset_pattern4(dst, &val, dwords * 4);
-#elif defined(__GNUC__) && defined(__i386__)
+#if defined(__GNUC__) && defined(__i386__)
     int u0, u1, u2;
     __asm__ __volatile__ (
         "cld \n\t"
@@ -694,7 +688,7 @@
                                          size_t * outbytesleft);
 
 /**
- * This function converts a string between encodings in one pass, returning a
+ * This function converts a buffer or string between encodings in one pass, returning a
  * string that must be freed with SDL_free() or NULL on error.
  *
  * \since This function is available since SDL 2.0.0.
@@ -721,6 +715,20 @@
 #ifndef HAVE_STRLCAT
 size_t strlcat(char* dst, const char* src, size_t size);
 #endif
+
+#ifndef HAVE_WCSLCPY
+size_t wcslcpy(wchar_t *dst, const wchar_t *src, size_t size);
+#endif
+
+#ifndef HAVE_WCSLCAT
+size_t wcslcat(wchar_t *dst, const wchar_t *src, size_t size);
+#endif
+
+/* Starting LLVM 16, the analyser errors out if these functions do not have
+   their prototype defined (clang-diagnostic-implicit-function-declaration) */
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
 
 #define SDL_malloc malloc
 #define SDL_calloc calloc
--- a/vs2019_project/ft2-clone/sdl/include/SDL2/SDL_thread.h
+++ b/vs2019_project/ft2-clone/sdl/include/SDL2/SDL_thread.h
@@ -35,7 +35,7 @@
 #include "SDL_atomic.h"
 #include "SDL_mutex.h"
 
-#if defined(__WIN32__) || defined(__GDK__)
+#if (defined(__WIN32__) || defined(__GDK__)) && !defined(__WINRT__)
 #include <process.h> /* _beginthreadex() and _endthreadex() */
 #endif
 #if defined(__OS2__) /* for _beginthread() and _endthread() */
@@ -88,7 +88,7 @@
 typedef int (SDLCALL * SDL_ThreadFunction) (void *data);
 
 
-#if defined(__WIN32__) || defined(__GDK__)
+#if (defined(__WIN32__) || defined(__GDK__)) && !defined(__WINRT__)
 /**
  *  \file SDL_thread.h
  *
--- a/vs2019_project/ft2-clone/sdl/include/SDL2/SDL_version.h
+++ b/vs2019_project/ft2-clone/sdl/include/SDL2/SDL_version.h
@@ -58,8 +58,8 @@
 /* Printable format: "%d.%d.%d", MAJOR, MINOR, PATCHLEVEL
 */
 #define SDL_MAJOR_VERSION   2
-#define SDL_MINOR_VERSION   26
-#define SDL_PATCHLEVEL      5
+#define SDL_MINOR_VERSION   28
+#define SDL_PATCHLEVEL      0
 
 /**
  * Macro to determine SDL version program was compiled against.
--- a/vs2019_project/ft2-clone/sdl/include/SDL2/SDL_video.h
+++ b/vs2019_project/ft2-clone/sdl/include/SDL2/SDL_video.h
@@ -187,7 +187,8 @@
     SDL_DISPLAYEVENT_NONE,          /**< Never used */
     SDL_DISPLAYEVENT_ORIENTATION,   /**< Display orientation has changed to data1 */
     SDL_DISPLAYEVENT_CONNECTED,     /**< Display has been added to the system */
-    SDL_DISPLAYEVENT_DISCONNECTED   /**< Display has been removed from the system */
+    SDL_DISPLAYEVENT_DISCONNECTED,  /**< Display has been removed from the system */
+    SDL_DISPLAYEVENT_MOVED          /**< Display has changed position */
 } SDL_DisplayEventID;
 
 /**
@@ -1275,6 +1276,17 @@
                                                     Uint32 flags);
 
 /**
+ * Return whether the window has a surface associated with it.
+ *
+ * \returns SDL_TRUE if there is a surface associated with the window, or SDL_FALSE otherwise.
+ *
+ * \since This function is available since SDL 2.28.0.
+ *
+ * \sa SDL_GetWindowSurface
+ */
+extern DECLSPEC SDL_bool SDLCALL SDL_HasWindowSurface(SDL_Window *window);
+
+/**
  * Get the SDL surface associated with the window.
  *
  * A new surface will be created with the optimal format for the window, if
@@ -1294,6 +1306,8 @@
  *
  * \since This function is available since SDL 2.0.0.
  *
+ * \sa SDL_DestroyWindowSurface
+ * \sa SDL_HasWindowSurface
  * \sa SDL_UpdateWindowSurface
  * \sa SDL_UpdateWindowSurfaceRects
  */
@@ -1328,7 +1342,7 @@
  *
  * \param window the window to update
  * \param rects an array of SDL_Rect structures representing areas of the
- *              surface to copy
+ *              surface to copy, in pixels
  * \param numrects the number of rectangles
  * \returns 0 on success or a negative error code on failure; call
  *          SDL_GetError() for more information.
@@ -1341,6 +1355,20 @@
 extern DECLSPEC int SDLCALL SDL_UpdateWindowSurfaceRects(SDL_Window * window,
                                                          const SDL_Rect * rects,
                                                          int numrects);
+
+/**
+ * Destroy the surface associated with the window.
+ *
+ * \param window the window to update
+ * \returns 0 on success or a negative error code on failure; call
+ *          SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 2.28.0.
+ *
+ * \sa SDL_GetWindowSurface
+ * \sa SDL_HasWindowSurface
+ */
+extern DECLSPEC int SDLCALL SDL_DestroyWindowSurface(SDL_Window *window);
 
 /**
  * Set a window's input grab mode.
--- a/vs2019_project/ft2-clone/sdl/include/SDL2/begin_code.h
+++ b/vs2019_project/ft2-clone/sdl/include/SDL2/begin_code.h
@@ -28,10 +28,10 @@
  */
 
 /* This shouldn't be nested -- included it around code only. */
-#ifdef _begin_code_h
+#ifdef SDL_begin_code_h
 #error Nested inclusion of begin_code.h
 #endif
-#define _begin_code_h
+#define SDL_begin_code_h
 
 #ifndef SDL_DEPRECATED
 #  if defined(__GNUC__) && (__GNUC__ >= 4)  /* technically, this arrived in gcc 3.1, but oh well. */
@@ -171,17 +171,17 @@
 #define SDL_FALLTHROUGH [[fallthrough]]
 #else
 #if defined(__has_attribute)
-#define _HAS_FALLTHROUGH __has_attribute(__fallthrough__)
+#define SDL_HAS_FALLTHROUGH __has_attribute(__fallthrough__)
 #else
-#define _HAS_FALLTHROUGH 0
+#define SDL_HAS_FALLTHROUGH 0
 #endif /* __has_attribute */
-#if _HAS_FALLTHROUGH && \
+#if SDL_HAS_FALLTHROUGH && \
    ((defined(__GNUC__) && __GNUC__ >= 7) || \
     (defined(__clang_major__) && __clang_major__ >= 10))
 #define SDL_FALLTHROUGH __attribute__((__fallthrough__))
 #else
 #define SDL_FALLTHROUGH do {} while (0) /* fallthrough */
-#endif /* _HAS_FALLTHROUGH */
-#undef _HAS_FALLTHROUGH
+#endif /* SDL_HAS_FALLTHROUGH */
+#undef SDL_HAS_FALLTHROUGH
 #endif /* C++17 or C2x */
 #endif /* SDL_FALLTHROUGH not defined */
--- a/vs2019_project/ft2-clone/sdl/include/SDL2/close_code.h
+++ b/vs2019_project/ft2-clone/sdl/include/SDL2/close_code.h
@@ -26,10 +26,10 @@
  *  after you finish any function and structure declarations in your headers
  */
 
-#ifndef _begin_code_h
+#ifndef SDL_begin_code_h
 #error close_code.h included without matching begin_code.h
 #endif
-#undef _begin_code_h
+#undef SDL_begin_code_h
 
 /* Reset structure packing at previous byte alignment */
 #if defined(_MSC_VER) || defined(__MWERKS__) || defined(__BORLANDC__)
binary files a/vs2019_project/ft2-clone/sdl/lib/SDL2.lib b/vs2019_project/ft2-clone/sdl/lib/SDL2.lib differ
binary files a/vs2019_project/ft2-clone/sdl/lib/SDL2main.lib b/vs2019_project/ft2-clone/sdl/lib/SDL2main.lib differ
binary files a/vs2019_project/ft2-clone/sdl/lib64/SDL2.lib b/vs2019_project/ft2-clone/sdl/lib64/SDL2.lib differ
binary files a/vs2019_project/ft2-clone/sdl/lib64/SDL2main.lib b/vs2019_project/ft2-clone/sdl/lib64/SDL2main.lib differ