/*
 * Copyright 2014 Blender Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License
 */

#ifdef _MSC_VER
#  define snprintf _snprintf
#  define popen _popen
#  define pclose _pclose
#  define _CRT_SECURE_NO_WARNINGS
#endif

#include "sdlew.h"

#include "SDL2/SDL.h"
#include "SDL2/SDL_syswm.h"

#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>

#ifdef _WIN32
#  define WIN32_LEAN_AND_MEAN
#  define VC_EXTRALEAN
#  include <windows.h>

/* Utility macros. */

typedef HMODULE DynamicLibrary;

#  define dynamic_library_open(path)         LoadLibrary(path)
#  define dynamic_library_close(lib)         FreeLibrary(lib)
#  define dynamic_library_find(lib, symbol)  GetProcAddress(lib, symbol)
#else
#  include <dlfcn.h>

typedef void* DynamicLibrary;

#  define dynamic_library_open(path)         dlopen(path, RTLD_NOW)
#  define dynamic_library_close(lib)         dlclose(lib)
#  define dynamic_library_find(lib, symbol)  dlsym(lib, symbol)
#endif

#define SDL_LIBRARY_FIND_CHECKED(name)         name = (t##name *)dynamic_library_find(lib, #name);         assert(name);

#define SDL_LIBRARY_FIND(name)         name = (t##name *)dynamic_library_find(lib, #name);

static DynamicLibrary lib;

tSDL_GetPlatform *SDL_GetPlatform;
tSDL_memcpy *SDL_memcpy;
#ifndef HAVE_ALLOCA
tSDL_malloc *SDL_malloc;
#endif
tSDL_calloc *SDL_calloc;
tSDL_realloc *SDL_realloc;
tSDL_free *SDL_free;
tSDL_getenv *SDL_getenv;
tSDL_setenv *SDL_setenv;
tSDL_qsort *SDL_qsort;
tSDL_abs *SDL_abs;
tSDL_isdigit *SDL_isdigit;
tSDL_isspace *SDL_isspace;
tSDL_toupper *SDL_toupper;
tSDL_tolower *SDL_tolower;
tSDL_memset *SDL_memset;
tSDL_memmove *SDL_memmove;
tSDL_memcmp *SDL_memcmp;
tSDL_wcslen *SDL_wcslen;
tSDL_wcslcpy *SDL_wcslcpy;
tSDL_wcslcat *SDL_wcslcat;
tSDL_strlen *SDL_strlen;
tSDL_strlcpy *SDL_strlcpy;
tSDL_utf8strlcpy *SDL_utf8strlcpy;
tSDL_strlcat *SDL_strlcat;
tSDL_strdup *SDL_strdup;
tSDL_strrev *SDL_strrev;
tSDL_strupr *SDL_strupr;
tSDL_strlwr *SDL_strlwr;
tSDL_strchr *SDL_strchr;
tSDL_strrchr *SDL_strrchr;
tSDL_strstr *SDL_strstr;
tSDL_itoa *SDL_itoa;
tSDL_uitoa *SDL_uitoa;
tSDL_ltoa *SDL_ltoa;
tSDL_ultoa *SDL_ultoa;
tSDL_lltoa *SDL_lltoa;
tSDL_ulltoa *SDL_ulltoa;
tSDL_atoi *SDL_atoi;
tSDL_atof *SDL_atof;
tSDL_strtol *SDL_strtol;
tSDL_strtoll *SDL_strtoll;
tSDL_strtoull *SDL_strtoull;
tSDL_strtod *SDL_strtod;
tSDL_strcmp *SDL_strcmp;
tSDL_strncmp *SDL_strncmp;
tSDL_strcasecmp *SDL_strcasecmp;
tSDL_strncasecmp *SDL_strncasecmp;
tSDL_sscanf *SDL_sscanf;
tSDL_snprintf *SDL_snprintf;
tSDL_vsnprintf *SDL_vsnprintf;
tSDL_atan *SDL_atan;
tSDL_atan2 *SDL_atan2;
tSDL_ceil *SDL_ceil;
tSDL_copysign *SDL_copysign;
tSDL_cos *SDL_cos;
tSDL_cosf *SDL_cosf;
tSDL_fabs *SDL_fabs;
tSDL_floor *SDL_floor;
tSDL_log *SDL_log;
tSDL_pow *SDL_pow;
tSDL_scalbn *SDL_scalbn;
tSDL_sin *SDL_sin;
tSDL_sinf *SDL_sinf;
tSDL_sqrt *SDL_sqrt;
tSDL_iconv_open *SDL_iconv_open;
tSDL_iconv_close *SDL_iconv_close;
tSDL_iconv *SDL_iconv;
tSDL_iconv_string *SDL_iconv_string;
tSDL_GetNumRenderDrivers *SDL_GetNumRenderDrivers;
tSDL_GetRenderDriverInfo *SDL_GetRenderDriverInfo;
tSDL_CreateWindowAndRenderer *SDL_CreateWindowAndRenderer;
tSDL_CreateRenderer *SDL_CreateRenderer;
tSDL_CreateSoftwareRenderer *SDL_CreateSoftwareRenderer;
tSDL_GetRenderer *SDL_GetRenderer;
tSDL_GetRendererInfo *SDL_GetRendererInfo;
tSDL_GetRendererOutputSize *SDL_GetRendererOutputSize;
tSDL_CreateTexture *SDL_CreateTexture;
tSDL_CreateTextureFromSurface *SDL_CreateTextureFromSurface;
tSDL_QueryTexture *SDL_QueryTexture;
tSDL_SetTextureColorMod *SDL_SetTextureColorMod;
tSDL_GetTextureColorMod *SDL_GetTextureColorMod;
tSDL_SetTextureAlphaMod *SDL_SetTextureAlphaMod;
tSDL_GetTextureAlphaMod *SDL_GetTextureAlphaMod;
tSDL_SetTextureBlendMode *SDL_SetTextureBlendMode;
tSDL_GetTextureBlendMode *SDL_GetTextureBlendMode;
tSDL_UpdateTexture *SDL_UpdateTexture;
tSDL_LockTexture *SDL_LockTexture;
tSDL_UnlockTexture *SDL_UnlockTexture;
tSDL_RenderTargetSupported *SDL_RenderTargetSupported;
tSDL_SetRenderTarget *SDL_SetRenderTarget;
tSDL_GetRenderTarget *SDL_GetRenderTarget;
tSDL_RenderSetLogicalSize *SDL_RenderSetLogicalSize;
tSDL_RenderGetLogicalSize *SDL_RenderGetLogicalSize;
tSDL_RenderSetViewport *SDL_RenderSetViewport;
tSDL_RenderGetViewport *SDL_RenderGetViewport;
tSDL_RenderSetClipRect *SDL_RenderSetClipRect;
tSDL_RenderGetClipRect *SDL_RenderGetClipRect;
tSDL_RenderSetScale *SDL_RenderSetScale;
tSDL_RenderGetScale *SDL_RenderGetScale;
tSDL_SetRenderDrawBlendMode *SDL_SetRenderDrawBlendMode;
tSDL_GetRenderDrawBlendMode *SDL_GetRenderDrawBlendMode;
tSDL_RenderClear *SDL_RenderClear;
tSDL_RenderDrawPoint *SDL_RenderDrawPoint;
tSDL_RenderDrawPoints *SDL_RenderDrawPoints;
tSDL_RenderDrawLine *SDL_RenderDrawLine;
tSDL_RenderDrawLines *SDL_RenderDrawLines;
tSDL_RenderDrawRect *SDL_RenderDrawRect;
tSDL_RenderDrawRects *SDL_RenderDrawRects;
tSDL_RenderFillRect *SDL_RenderFillRect;
tSDL_RenderFillRects *SDL_RenderFillRects;
tSDL_RenderCopy *SDL_RenderCopy;
tSDL_RenderCopyEx *SDL_RenderCopyEx;
tSDL_RenderReadPixels *SDL_RenderReadPixels;
tSDL_RenderPresent *SDL_RenderPresent;
tSDL_DestroyTexture *SDL_DestroyTexture;
tSDL_DestroyRenderer *SDL_DestroyRenderer;
tSDL_GL_BindTexture *SDL_GL_BindTexture;
tSDL_GL_UnbindTexture *SDL_GL_UnbindTexture;
tSDL_LoadObject *SDL_LoadObject;
tSDL_LoadFunction *SDL_LoadFunction;
tSDL_UnloadObject *SDL_UnloadObject;
tSDL_ReportAssertion *SDL_ReportAssertion;
tSDL_SetAssertionHandler *SDL_SetAssertionHandler;
tSDL_GetAssertionReport *SDL_GetAssertionReport;
tSDL_ResetAssertionReport *SDL_ResetAssertionReport;
tSDL_AtomicTryLock *SDL_AtomicTryLock;
tSDL_AtomicLock *SDL_AtomicLock;
tSDL_AtomicUnlock *SDL_AtomicUnlock;
tSDL_HasIntersection *SDL_HasIntersection;
tSDL_IntersectRect *SDL_IntersectRect;
tSDL_UnionRect *SDL_UnionRect;
tSDL_EnclosePoints *SDL_EnclosePoints;
tSDL_IntersectRectAndLine *SDL_IntersectRectAndLine;
tSDL_LogSetAllPriority *SDL_LogSetAllPriority;
tSDL_LogSetPriority *SDL_LogSetPriority;
tSDL_LogGetPriority *SDL_LogGetPriority;
tSDL_LogResetPriorities *SDL_LogResetPriorities;
tSDL_Log *SDL_Log;
tSDL_LogVerbose *SDL_LogVerbose;
tSDL_LogDebug *SDL_LogDebug;
tSDL_LogInfo *SDL_LogInfo;
tSDL_LogWarn *SDL_LogWarn;
tSDL_LogError *SDL_LogError;
tSDL_LogCritical *SDL_LogCritical;
tSDL_LogMessage *SDL_LogMessage;
tSDL_LogMessageV *SDL_LogMessageV;
tSDL_LogGetOutputFunction *SDL_LogGetOutputFunction;
tSDL_LogSetOutputFunction *SDL_LogSetOutputFunction;
tSDL_CreateMutex *SDL_CreateMutex;
tSDL_LockMutex *SDL_LockMutex;
tSDL_TryLockMutex *SDL_TryLockMutex;
tSDL_UnlockMutex *SDL_UnlockMutex;
tSDL_DestroyMutex *SDL_DestroyMutex;
tSDL_CreateSemaphore *SDL_CreateSemaphore;
tSDL_DestroySemaphore *SDL_DestroySemaphore;
tSDL_SemWait *SDL_SemWait;
tSDL_SemTryWait *SDL_SemTryWait;
tSDL_SemWaitTimeout *SDL_SemWaitTimeout;
tSDL_SemPost *SDL_SemPost;
tSDL_SemValue *SDL_SemValue;
tSDL_CreateCond *SDL_CreateCond;
tSDL_DestroyCond *SDL_DestroyCond;
tSDL_CondSignal *SDL_CondSignal;
tSDL_CondBroadcast *SDL_CondBroadcast;
tSDL_CondWait *SDL_CondWait;
tSDL_CondWaitTimeout *SDL_CondWaitTimeout;
tSDL_CreateRGBSurface *SDL_CreateRGBSurface;
tSDL_CreateRGBSurfaceFrom *SDL_CreateRGBSurfaceFrom;
tSDL_FreeSurface *SDL_FreeSurface;
tSDL_SetSurfacePalette *SDL_SetSurfacePalette;
tSDL_LockSurface *SDL_LockSurface;
tSDL_UnlockSurface *SDL_UnlockSurface;
tSDL_LoadBMP_RW *SDL_LoadBMP_RW;
tSDL_SaveBMP_RW *SDL_SaveBMP_RW;
tSDL_SetSurfaceRLE *SDL_SetSurfaceRLE;
tSDL_SetColorKey *SDL_SetColorKey;
tSDL_GetColorKey *SDL_GetColorKey;
tSDL_SetSurfaceColorMod *SDL_SetSurfaceColorMod;
tSDL_GetSurfaceColorMod *SDL_GetSurfaceColorMod;
tSDL_SetSurfaceAlphaMod *SDL_SetSurfaceAlphaMod;
tSDL_GetSurfaceAlphaMod *SDL_GetSurfaceAlphaMod;
tSDL_SetSurfaceBlendMode *SDL_SetSurfaceBlendMode;
tSDL_GetSurfaceBlendMode *SDL_GetSurfaceBlendMode;
tSDL_SetClipRect *SDL_SetClipRect;
tSDL_GetClipRect *SDL_GetClipRect;
tSDL_ConvertSurface *SDL_ConvertSurface;
tSDL_ConvertSurfaceFormat *SDL_ConvertSurfaceFormat;
tSDL_ConvertPixels *SDL_ConvertPixels;
tSDL_FillRect *SDL_FillRect;
tSDL_FillRects *SDL_FillRects;
tSDL_UpperBlit *SDL_UpperBlit;
tSDL_LowerBlit *SDL_LowerBlit;
tSDL_SoftStretch *SDL_SoftStretch;
tSDL_UpperBlitScaled *SDL_UpperBlitScaled;
tSDL_LowerBlitScaled *SDL_LowerBlitScaled;
tSDL_PumpEvents *SDL_PumpEvents;
tSDL_PeepEvents *SDL_PeepEvents;
tSDL_HasEvent *SDL_HasEvent;
tSDL_HasEvents *SDL_HasEvents;
tSDL_FlushEvent *SDL_FlushEvent;
tSDL_FlushEvents *SDL_FlushEvents;
tSDL_PollEvent *SDL_PollEvent;
tSDL_WaitEvent *SDL_WaitEvent;
tSDL_WaitEventTimeout *SDL_WaitEventTimeout;
tSDL_PushEvent *SDL_PushEvent;
tSDL_SetEventFilter *SDL_SetEventFilter;
tSDL_GetEventFilter *SDL_GetEventFilter;
tSDL_AddEventWatch *SDL_AddEventWatch;
tSDL_DelEventWatch *SDL_DelEventWatch;
tSDL_FilterEvents *SDL_FilterEvents;
tSDL_EventState *SDL_EventState;
tSDL_RegisterEvents *SDL_RegisterEvents;
tSDL_GetMouseFocus *SDL_GetMouseFocus;
tSDL_GetMouseState *SDL_GetMouseState;
tSDL_GetRelativeMouseState *SDL_GetRelativeMouseState;
tSDL_WarpMouseInWindow *SDL_WarpMouseInWindow;
tSDL_SetRelativeMouseMode *SDL_SetRelativeMouseMode;
tSDL_GetRelativeMouseMode *SDL_GetRelativeMouseMode;
tSDL_CreateCursor *SDL_CreateCursor;
tSDL_CreateColorCursor *SDL_CreateColorCursor;
tSDL_CreateSystemCursor *SDL_CreateSystemCursor;
tSDL_SetCursor *SDL_SetCursor;
tSDL_GetCursor *SDL_GetCursor;
tSDL_GetDefaultCursor *SDL_GetDefaultCursor;
tSDL_FreeCursor *SDL_FreeCursor;
tSDL_ShowCursor *SDL_ShowCursor;
tSDL_GetThreadName *SDL_GetThreadName;
tSDL_ThreadID *SDL_ThreadID;
tSDL_GetThreadID *SDL_GetThreadID;
tSDL_SetThreadPriority *SDL_SetThreadPriority;
tSDL_WaitThread *SDL_WaitThread;
tSDL_TLSCreate *SDL_TLSCreate;
tSDL_TLSGet *SDL_TLSGet;
tSDL_TLSSet *SDL_TLSSet;
tSDL_GetKeyboardFocus *SDL_GetKeyboardFocus;
tSDL_GetKeyboardState *SDL_GetKeyboardState;
tSDL_GetModState *SDL_GetModState;
tSDL_SetModState *SDL_SetModState;
tSDL_GetKeyFromScancode *SDL_GetKeyFromScancode;
tSDL_GetScancodeFromKey *SDL_GetScancodeFromKey;
tSDL_GetScancodeName *SDL_GetScancodeName;
tSDL_GetScancodeFromName *SDL_GetScancodeFromName;
tSDL_GetKeyName *SDL_GetKeyName;
tSDL_GetKeyFromName *SDL_GetKeyFromName;
tSDL_StartTextInput *SDL_StartTextInput;
tSDL_IsTextInputActive *SDL_IsTextInputActive;
tSDL_StopTextInput *SDL_StopTextInput;
tSDL_SetTextInputRect *SDL_SetTextInputRect;
tSDL_HasScreenKeyboardSupport *SDL_HasScreenKeyboardSupport;
tSDL_IsScreenKeyboardShown *SDL_IsScreenKeyboardShown;
tSDL_GameControllerAddMapping *SDL_GameControllerAddMapping;
tSDL_GameControllerMappingForGUID *SDL_GameControllerMappingForGUID;
tSDL_GameControllerMapping *SDL_GameControllerMapping;
tSDL_IsGameController *SDL_IsGameController;
tSDL_GameControllerNameForIndex *SDL_GameControllerNameForIndex;
tSDL_GameControllerOpen *SDL_GameControllerOpen;
tSDL_GameControllerName *SDL_GameControllerName;
tSDL_GameControllerGetAttached *SDL_GameControllerGetAttached;
tSDL_GameControllerGetJoystick *SDL_GameControllerGetJoystick;
tSDL_GameControllerEventState *SDL_GameControllerEventState;
tSDL_GameControllerUpdate *SDL_GameControllerUpdate;
tSDL_GameControllerGetAxisFromString *SDL_GameControllerGetAxisFromString;
tSDL_GameControllerGetButtonFromString *SDL_GameControllerGetButtonFromString;
tSDL_GameControllerGetButton *SDL_GameControllerGetButton;
tSDL_GameControllerClose *SDL_GameControllerClose;
tSDL_GetNumAudioDrivers *SDL_GetNumAudioDrivers;
tSDL_GetAudioDriver *SDL_GetAudioDriver;
tSDL_AudioInit *SDL_AudioInit;
tSDL_AudioQuit *SDL_AudioQuit;
tSDL_GetCurrentAudioDriver *SDL_GetCurrentAudioDriver;
tSDL_OpenAudio *SDL_OpenAudio;
tSDL_GetNumAudioDevices *SDL_GetNumAudioDevices;
tSDL_GetAudioDeviceName *SDL_GetAudioDeviceName;
tSDL_OpenAudioDevice *SDL_OpenAudioDevice;
tSDL_GetAudioStatus *SDL_GetAudioStatus;
tSDL_PauseAudio *SDL_PauseAudio;
tSDL_PauseAudioDevice *SDL_PauseAudioDevice;
tSDL_LoadWAV_RW *SDL_LoadWAV_RW;
tSDL_FreeWAV *SDL_FreeWAV;
tSDL_BuildAudioCVT *SDL_BuildAudioCVT;
tSDL_ConvertAudio *SDL_ConvertAudio;
tSDL_MixAudio *SDL_MixAudio;
tSDL_MixAudioFormat *SDL_MixAudioFormat;
tSDL_LockAudio *SDL_LockAudio;
tSDL_LockAudioDevice *SDL_LockAudioDevice;
tSDL_UnlockAudio *SDL_UnlockAudio;
tSDL_UnlockAudioDevice *SDL_UnlockAudioDevice;
tSDL_CloseAudio *SDL_CloseAudio;
tSDL_CloseAudioDevice *SDL_CloseAudioDevice;
tSDL_GetNumVideoDrivers *SDL_GetNumVideoDrivers;
tSDL_GetVideoDriver *SDL_GetVideoDriver;
tSDL_VideoInit *SDL_VideoInit;
tSDL_VideoQuit *SDL_VideoQuit;
tSDL_GetCurrentVideoDriver *SDL_GetCurrentVideoDriver;
tSDL_GetNumVideoDisplays *SDL_GetNumVideoDisplays;
tSDL_GetDisplayName *SDL_GetDisplayName;
tSDL_GetDisplayBounds *SDL_GetDisplayBounds;
tSDL_GetNumDisplayModes *SDL_GetNumDisplayModes;
tSDL_GetDisplayMode *SDL_GetDisplayMode;
tSDL_GetDesktopDisplayMode *SDL_GetDesktopDisplayMode;
tSDL_GetCurrentDisplayMode *SDL_GetCurrentDisplayMode;
tSDL_GetClosestDisplayMode *SDL_GetClosestDisplayMode;
tSDL_GetWindowDisplayIndex *SDL_GetWindowDisplayIndex;
tSDL_SetWindowDisplayMode *SDL_SetWindowDisplayMode;
tSDL_GetWindowDisplayMode *SDL_GetWindowDisplayMode;
tSDL_GetWindowPixelFormat *SDL_GetWindowPixelFormat;
tSDL_CreateWindow *SDL_CreateWindow;
tSDL_CreateWindowFrom *SDL_CreateWindowFrom;
tSDL_GetWindowID *SDL_GetWindowID;
tSDL_GetWindowFromID *SDL_GetWindowFromID;
tSDL_GetWindowFlags *SDL_GetWindowFlags;
tSDL_SetWindowTitle *SDL_SetWindowTitle;
tSDL_GetWindowTitle *SDL_GetWindowTitle;
tSDL_SetWindowIcon *SDL_SetWindowIcon;
tSDL_GetWindowData *SDL_GetWindowData;
tSDL_SetWindowPosition *SDL_SetWindowPosition;
tSDL_GetWindowPosition *SDL_GetWindowPosition;
tSDL_SetWindowSize *SDL_SetWindowSize;
tSDL_GetWindowSize *SDL_GetWindowSize;
tSDL_SetWindowMinimumSize *SDL_SetWindowMinimumSize;
tSDL_GetWindowMinimumSize *SDL_GetWindowMinimumSize;
tSDL_SetWindowMaximumSize *SDL_SetWindowMaximumSize;
tSDL_GetWindowMaximumSize *SDL_GetWindowMaximumSize;
tSDL_SetWindowBordered *SDL_SetWindowBordered;
tSDL_ShowWindow *SDL_ShowWindow;
tSDL_HideWindow *SDL_HideWindow;
tSDL_RaiseWindow *SDL_RaiseWindow;
tSDL_MaximizeWindow *SDL_MaximizeWindow;
tSDL_MinimizeWindow *SDL_MinimizeWindow;
tSDL_RestoreWindow *SDL_RestoreWindow;
tSDL_SetWindowFullscreen *SDL_SetWindowFullscreen;
tSDL_GetWindowSurface *SDL_GetWindowSurface;
tSDL_UpdateWindowSurface *SDL_UpdateWindowSurface;
tSDL_UpdateWindowSurfaceRects *SDL_UpdateWindowSurfaceRects;
tSDL_SetWindowGrab *SDL_SetWindowGrab;
tSDL_GetWindowGrab *SDL_GetWindowGrab;
tSDL_SetWindowBrightness *SDL_SetWindowBrightness;
tSDL_GetWindowBrightness *SDL_GetWindowBrightness;
tSDL_SetWindowGammaRamp *SDL_SetWindowGammaRamp;
tSDL_GetWindowGammaRamp *SDL_GetWindowGammaRamp;
tSDL_DestroyWindow *SDL_DestroyWindow;
tSDL_IsScreenSaverEnabled *SDL_IsScreenSaverEnabled;
tSDL_EnableScreenSaver *SDL_EnableScreenSaver;
tSDL_DisableScreenSaver *SDL_DisableScreenSaver;
tSDL_GL_LoadLibrary *SDL_GL_LoadLibrary;
tSDL_GL_GetProcAddress *SDL_GL_GetProcAddress;
tSDL_GL_UnloadLibrary *SDL_GL_UnloadLibrary;
tSDL_GL_ExtensionSupported *SDL_GL_ExtensionSupported;
tSDL_GL_SetAttribute *SDL_GL_SetAttribute;
tSDL_GL_GetAttribute *SDL_GL_GetAttribute;
tSDL_GL_CreateContext *SDL_GL_CreateContext;
tSDL_GL_MakeCurrent *SDL_GL_MakeCurrent;
tSDL_GL_GetCurrentContext *SDL_GL_GetCurrentContext;
tSDL_GL_SetSwapInterval *SDL_GL_SetSwapInterval;
tSDL_GL_GetSwapInterval *SDL_GL_GetSwapInterval;
tSDL_GL_SwapWindow *SDL_GL_SwapWindow;
tSDL_GL_DeleteContext *SDL_GL_DeleteContext;
tSDL_RWFromFile *SDL_RWFromFile;
tSDL_RWFromFP *SDL_RWFromFP;
tSDL_RWFromFP *SDL_RWFromFP;
tSDL_RWFromMem *SDL_RWFromMem;
tSDL_RWFromConstMem *SDL_RWFromConstMem;
tSDL_AllocRW *SDL_AllocRW;
tSDL_FreeRW *SDL_FreeRW;
tSDL_ReadU8 *SDL_ReadU8;
tSDL_ReadLE16 *SDL_ReadLE16;
tSDL_ReadBE16 *SDL_ReadBE16;
tSDL_ReadLE32 *SDL_ReadLE32;
tSDL_ReadBE32 *SDL_ReadBE32;
tSDL_ReadLE64 *SDL_ReadLE64;
tSDL_ReadBE64 *SDL_ReadBE64;
tSDL_WriteU8 *SDL_WriteU8;
tSDL_WriteLE16 *SDL_WriteLE16;
tSDL_WriteBE16 *SDL_WriteBE16;
tSDL_WriteLE32 *SDL_WriteLE32;
tSDL_WriteBE32 *SDL_WriteBE32;
tSDL_WriteLE64 *SDL_WriteLE64;
tSDL_WriteBE64 *SDL_WriteBE64;
tSDL_Init *SDL_Init;
tSDL_InitSubSystem *SDL_InitSubSystem;
tSDL_QuitSubSystem *SDL_QuitSubSystem;
tSDL_WasInit *SDL_WasInit;
tSDL_Quit *SDL_Quit;
tSDL_GetVersion *SDL_GetVersion;
tSDL_GetRevision *SDL_GetRevision;
tSDL_GetRevisionNumber *SDL_GetRevisionNumber;
tSDL_GetTicks *SDL_GetTicks;
tSDL_GetPerformanceCounter *SDL_GetPerformanceCounter;
tSDL_GetPerformanceFrequency *SDL_GetPerformanceFrequency;
tSDL_Delay *SDL_Delay;
tSDL_AddTimer *SDL_AddTimer;
tSDL_RemoveTimer *SDL_RemoveTimer;
tSDL_SetHintWithPriority *SDL_SetHintWithPriority;
tSDL_SetHint *SDL_SetHint;
tSDL_GetHint *SDL_GetHint;
tSDL_AddHintCallback *SDL_AddHintCallback;
tSDL_DelHintCallback *SDL_DelHintCallback;
tSDL_ClearHints *SDL_ClearHints;
tSDL_NumJoysticks *SDL_NumJoysticks;
tSDL_JoystickNameForIndex *SDL_JoystickNameForIndex;
tSDL_JoystickOpen *SDL_JoystickOpen;
tSDL_JoystickName *SDL_JoystickName;
tSDL_JoystickGetDeviceGUID *SDL_JoystickGetDeviceGUID;
tSDL_JoystickGetGUID *SDL_JoystickGetGUID;
tSDL_JoystickGetGUIDFromString *SDL_JoystickGetGUIDFromString;
tSDL_JoystickGetAttached *SDL_JoystickGetAttached;
tSDL_JoystickInstanceID *SDL_JoystickInstanceID;
tSDL_JoystickNumAxes *SDL_JoystickNumAxes;
tSDL_JoystickNumBalls *SDL_JoystickNumBalls;
tSDL_JoystickNumHats *SDL_JoystickNumHats;
tSDL_JoystickNumButtons *SDL_JoystickNumButtons;
tSDL_JoystickUpdate *SDL_JoystickUpdate;
tSDL_JoystickEventState *SDL_JoystickEventState;
tSDL_JoystickGetAxis *SDL_JoystickGetAxis;
tSDL_JoystickGetHat *SDL_JoystickGetHat;
tSDL_JoystickGetBall *SDL_JoystickGetBall;
tSDL_JoystickGetButton *SDL_JoystickGetButton;
tSDL_JoystickClose *SDL_JoystickClose;
tSDL_RecordGesture *SDL_RecordGesture;
tSDL_SaveAllDollarTemplates *SDL_SaveAllDollarTemplates;
tSDL_SaveDollarTemplate *SDL_SaveDollarTemplate;
tSDL_LoadDollarTemplates *SDL_LoadDollarTemplates;
tSDL_NumHaptics *SDL_NumHaptics;
tSDL_HapticName *SDL_HapticName;
tSDL_HapticOpen *SDL_HapticOpen;
tSDL_HapticOpened *SDL_HapticOpened;
tSDL_HapticIndex *SDL_HapticIndex;
tSDL_MouseIsHaptic *SDL_MouseIsHaptic;
tSDL_HapticOpenFromMouse *SDL_HapticOpenFromMouse;
tSDL_JoystickIsHaptic *SDL_JoystickIsHaptic;
tSDL_HapticOpenFromJoystick *SDL_HapticOpenFromJoystick;
tSDL_HapticClose *SDL_HapticClose;
tSDL_HapticNumEffects *SDL_HapticNumEffects;
tSDL_HapticNumEffectsPlaying *SDL_HapticNumEffectsPlaying;
tSDL_HapticNumAxes *SDL_HapticNumAxes;
tSDL_HapticEffectSupported *SDL_HapticEffectSupported;
tSDL_HapticNewEffect *SDL_HapticNewEffect;
tSDL_HapticUpdateEffect *SDL_HapticUpdateEffect;
tSDL_HapticRunEffect *SDL_HapticRunEffect;
tSDL_HapticStopEffect *SDL_HapticStopEffect;
tSDL_HapticDestroyEffect *SDL_HapticDestroyEffect;
tSDL_HapticGetEffectStatus *SDL_HapticGetEffectStatus;
tSDL_HapticSetGain *SDL_HapticSetGain;
tSDL_HapticSetAutocenter *SDL_HapticSetAutocenter;
tSDL_HapticPause *SDL_HapticPause;
tSDL_HapticUnpause *SDL_HapticUnpause;
tSDL_HapticStopAll *SDL_HapticStopAll;
tSDL_HapticRumbleSupported *SDL_HapticRumbleSupported;
tSDL_HapticRumbleInit *SDL_HapticRumbleInit;
tSDL_HapticRumblePlay *SDL_HapticRumblePlay;
tSDL_HapticRumbleStop *SDL_HapticRumbleStop;
tSDL_ShowMessageBox *SDL_ShowMessageBox;
tSDL_ShowSimpleMessageBox *SDL_ShowSimpleMessageBox;
tSDL_PixelFormatEnumToMasks *SDL_PixelFormatEnumToMasks;
tSDL_MasksToPixelFormatEnum *SDL_MasksToPixelFormatEnum;
tSDL_AllocFormat *SDL_AllocFormat;
tSDL_FreeFormat *SDL_FreeFormat;
tSDL_AllocPalette *SDL_AllocPalette;
tSDL_SetPixelFormatPalette *SDL_SetPixelFormatPalette;
tSDL_SetPaletteColors *SDL_SetPaletteColors;
tSDL_FreePalette *SDL_FreePalette;
tSDL_MapRGB *SDL_MapRGB;
tSDL_MapRGBA *SDL_MapRGBA;
tSDL_GetRGB *SDL_GetRGB;
tSDL_GetRGBA *SDL_GetRGBA;
tSDL_CalculateGammaRamp *SDL_CalculateGammaRamp;
tSDL_GetPowerInfo *SDL_GetPowerInfo;
tSDL_GetCPUCount *SDL_GetCPUCount;
tSDL_GetCPUCacheLineSize *SDL_GetCPUCacheLineSize;
tSDL_HasRDTSC *SDL_HasRDTSC;
tSDL_HasAltiVec *SDL_HasAltiVec;
tSDL_HasMMX *SDL_HasMMX;
tSDL_Has3DNow *SDL_Has3DNow;
tSDL_HasSSE *SDL_HasSSE;
tSDL_HasSSE2 *SDL_HasSSE2;
tSDL_HasSSE3 *SDL_HasSSE3;
tSDL_HasSSE41 *SDL_HasSSE41;
tSDL_HasSSE42 *SDL_HasSSE42;
tSDL_GetNumTouchDevices *SDL_GetNumTouchDevices;
tSDL_GetTouchDevice *SDL_GetTouchDevice;
tSDL_GetNumTouchFingers *SDL_GetNumTouchFingers;
tSDL_GetTouchFinger *SDL_GetTouchFinger;
tSDL_SetError *SDL_SetError;
tSDL_GetError *SDL_GetError;
tSDL_ClearError *SDL_ClearError;
tSDL_Error *SDL_Error;
tSDL_SetClipboardText *SDL_SetClipboardText;
tSDL_GetClipboardText *SDL_GetClipboardText;
tSDL_HasClipboardText *SDL_HasClipboardText;
tSDL_GetWindowWMInfo *SDL_GetWindowWMInfo;

static void sdlewExit(void) {
  if(lib != NULL) {
    /*  Ignore errors. */
    dynamic_library_close(lib);
    lib = NULL;
  }
}

/* Implementation function. */
int sdlewInit(void) {
  /* Library paths. */
#ifdef _WIN32
  /* Expected in c:/windows/system or similar, no path needed. */
  const char *paths[] = {"SDL2.dll", NULL};
#elif defined(__APPLE__)
  /* Default installation path. */
  const char *paths[] = {"/usr/local/cuda/lib/libSDL2.dylib", NULL};
#else
  const char *paths[] = {"libSDL2.so",
                         "libSDL2-2.0.so.0",
                         "libSDL.so",
                         NULL};
#endif
  static int initialized = 0;
  static int result = 0;
  int a, error;
  SDL_version version;

  if (initialized) {
    return result;
  }

  initialized = 1;

  error = atexit(sdlewExit);
  if (error) {
    result = SDLEW_ERROR_ATEXIT_FAILED;
    return result;
  }

  /* Load library. */
  for (a = 0; paths[a] != NULL && lib == NULL; ++a) {
    lib = dynamic_library_open(paths[a]);
  }

  if (lib == NULL) {
    result = SDLEW_ERROR_OPEN_FAILED;
    return result;
  }

  SDL_LIBRARY_FIND(SDL_GetPlatform);
  SDL_LIBRARY_FIND(SDL_memcpy);
#ifndef HAVE_ALLOCA
  SDL_LIBRARY_FIND(SDL_malloc);
#endif
  SDL_LIBRARY_FIND(SDL_calloc);
  SDL_LIBRARY_FIND(SDL_realloc);
  SDL_LIBRARY_FIND(SDL_free);
  SDL_LIBRARY_FIND(SDL_getenv);
  SDL_LIBRARY_FIND(SDL_setenv);
  SDL_LIBRARY_FIND(SDL_qsort);
  SDL_LIBRARY_FIND(SDL_abs);
  SDL_LIBRARY_FIND(SDL_isdigit);
  SDL_LIBRARY_FIND(SDL_isspace);
  SDL_LIBRARY_FIND(SDL_toupper);
  SDL_LIBRARY_FIND(SDL_tolower);
  SDL_LIBRARY_FIND(SDL_memset);
  SDL_LIBRARY_FIND(SDL_memmove);
  SDL_LIBRARY_FIND(SDL_memcmp);
  SDL_LIBRARY_FIND(SDL_wcslen);
  SDL_LIBRARY_FIND(SDL_wcslcpy);
  SDL_LIBRARY_FIND(SDL_wcslcat);
  SDL_LIBRARY_FIND(SDL_strlen);
  SDL_LIBRARY_FIND(SDL_strlcpy);
  SDL_LIBRARY_FIND(SDL_utf8strlcpy);
  SDL_LIBRARY_FIND(SDL_strlcat);
  SDL_LIBRARY_FIND(SDL_strdup);
  SDL_LIBRARY_FIND(SDL_strrev);
  SDL_LIBRARY_FIND(SDL_strupr);
  SDL_LIBRARY_FIND(SDL_strlwr);
  SDL_LIBRARY_FIND(SDL_strchr);
  SDL_LIBRARY_FIND(SDL_strrchr);
  SDL_LIBRARY_FIND(SDL_strstr);
  SDL_LIBRARY_FIND(SDL_itoa);
  SDL_LIBRARY_FIND(SDL_uitoa);
  SDL_LIBRARY_FIND(SDL_ltoa);
  SDL_LIBRARY_FIND(SDL_ultoa);
  SDL_LIBRARY_FIND(SDL_lltoa);
  SDL_LIBRARY_FIND(SDL_ulltoa);
  SDL_LIBRARY_FIND(SDL_atoi);
  SDL_LIBRARY_FIND(SDL_atof);
  SDL_LIBRARY_FIND(SDL_strtol);
  SDL_LIBRARY_FIND(SDL_strtoll);
  SDL_LIBRARY_FIND(SDL_strtoull);
  SDL_LIBRARY_FIND(SDL_strtod);
  SDL_LIBRARY_FIND(SDL_strcmp);
  SDL_LIBRARY_FIND(SDL_strncmp);
  SDL_LIBRARY_FIND(SDL_strcasecmp);
  SDL_LIBRARY_FIND(SDL_strncasecmp);
  SDL_LIBRARY_FIND(SDL_sscanf);
  SDL_LIBRARY_FIND(SDL_snprintf);
  SDL_LIBRARY_FIND(SDL_vsnprintf);
  SDL_LIBRARY_FIND(SDL_atan);
  SDL_LIBRARY_FIND(SDL_atan2);
  SDL_LIBRARY_FIND(SDL_ceil);
  SDL_LIBRARY_FIND(SDL_copysign);
  SDL_LIBRARY_FIND(SDL_cos);
  SDL_LIBRARY_FIND(SDL_cosf);
  SDL_LIBRARY_FIND(SDL_fabs);
  SDL_LIBRARY_FIND(SDL_floor);
  SDL_LIBRARY_FIND(SDL_log);
  SDL_LIBRARY_FIND(SDL_pow);
  SDL_LIBRARY_FIND(SDL_scalbn);
  SDL_LIBRARY_FIND(SDL_sin);
  SDL_LIBRARY_FIND(SDL_sinf);
  SDL_LIBRARY_FIND(SDL_sqrt);
  SDL_LIBRARY_FIND(SDL_iconv_open);
  SDL_LIBRARY_FIND(SDL_iconv_close);
  SDL_LIBRARY_FIND(SDL_iconv);
  SDL_LIBRARY_FIND(SDL_iconv_string);
  SDL_LIBRARY_FIND(SDL_GetNumRenderDrivers);
  SDL_LIBRARY_FIND(SDL_GetRenderDriverInfo);
  SDL_LIBRARY_FIND(SDL_CreateWindowAndRenderer);
  SDL_LIBRARY_FIND(SDL_CreateRenderer);
  SDL_LIBRARY_FIND(SDL_CreateSoftwareRenderer);
  SDL_LIBRARY_FIND(SDL_GetRenderer);
  SDL_LIBRARY_FIND(SDL_GetRendererInfo);
  SDL_LIBRARY_FIND(SDL_GetRendererOutputSize);
  SDL_LIBRARY_FIND(SDL_CreateTexture);
  SDL_LIBRARY_FIND(SDL_CreateTextureFromSurface);
  SDL_LIBRARY_FIND(SDL_QueryTexture);
  SDL_LIBRARY_FIND(SDL_SetTextureColorMod);
  SDL_LIBRARY_FIND(SDL_GetTextureColorMod);
  SDL_LIBRARY_FIND(SDL_SetTextureAlphaMod);
  SDL_LIBRARY_FIND(SDL_GetTextureAlphaMod);
  SDL_LIBRARY_FIND(SDL_SetTextureBlendMode);
  SDL_LIBRARY_FIND(SDL_GetTextureBlendMode);
  SDL_LIBRARY_FIND(SDL_UpdateTexture);
  SDL_LIBRARY_FIND(SDL_LockTexture);
  SDL_LIBRARY_FIND(SDL_UnlockTexture);
  SDL_LIBRARY_FIND(SDL_RenderTargetSupported);
  SDL_LIBRARY_FIND(SDL_SetRenderTarget);
  SDL_LIBRARY_FIND(SDL_GetRenderTarget);
  SDL_LIBRARY_FIND(SDL_RenderSetLogicalSize);
  SDL_LIBRARY_FIND(SDL_RenderGetLogicalSize);
  SDL_LIBRARY_FIND(SDL_RenderSetViewport);
  SDL_LIBRARY_FIND(SDL_RenderGetViewport);
  SDL_LIBRARY_FIND(SDL_RenderSetClipRect);
  SDL_LIBRARY_FIND(SDL_RenderGetClipRect);
  SDL_LIBRARY_FIND(SDL_RenderSetScale);
  SDL_LIBRARY_FIND(SDL_RenderGetScale);
  SDL_LIBRARY_FIND(SDL_SetRenderDrawBlendMode);
  SDL_LIBRARY_FIND(SDL_GetRenderDrawBlendMode);
  SDL_LIBRARY_FIND(SDL_RenderClear);
  SDL_LIBRARY_FIND(SDL_RenderDrawPoint);
  SDL_LIBRARY_FIND(SDL_RenderDrawPoints);
  SDL_LIBRARY_FIND(SDL_RenderDrawLine);
  SDL_LIBRARY_FIND(SDL_RenderDrawLines);
  SDL_LIBRARY_FIND(SDL_RenderDrawRect);
  SDL_LIBRARY_FIND(SDL_RenderDrawRects);
  SDL_LIBRARY_FIND(SDL_RenderFillRect);
  SDL_LIBRARY_FIND(SDL_RenderFillRects);
  SDL_LIBRARY_FIND(SDL_RenderCopy);
  SDL_LIBRARY_FIND(SDL_RenderCopyEx);
  SDL_LIBRARY_FIND(SDL_RenderReadPixels);
  SDL_LIBRARY_FIND(SDL_RenderPresent);
  SDL_LIBRARY_FIND(SDL_DestroyTexture);
  SDL_LIBRARY_FIND(SDL_DestroyRenderer);
  SDL_LIBRARY_FIND(SDL_GL_BindTexture);
  SDL_LIBRARY_FIND(SDL_GL_UnbindTexture);
  SDL_LIBRARY_FIND(SDL_LoadObject);
  SDL_LIBRARY_FIND(SDL_LoadFunction);
  SDL_LIBRARY_FIND(SDL_UnloadObject);
  SDL_LIBRARY_FIND(SDL_ReportAssertion);
  SDL_LIBRARY_FIND(SDL_SetAssertionHandler);
  SDL_LIBRARY_FIND(SDL_GetAssertionReport);
  SDL_LIBRARY_FIND(SDL_ResetAssertionReport);
  SDL_LIBRARY_FIND(SDL_AtomicTryLock);
  SDL_LIBRARY_FIND(SDL_AtomicLock);
  SDL_LIBRARY_FIND(SDL_AtomicUnlock);
  SDL_LIBRARY_FIND(SDL_HasIntersection);
  SDL_LIBRARY_FIND(SDL_IntersectRect);
  SDL_LIBRARY_FIND(SDL_UnionRect);
  SDL_LIBRARY_FIND(SDL_EnclosePoints);
  SDL_LIBRARY_FIND(SDL_IntersectRectAndLine);
  SDL_LIBRARY_FIND(SDL_LogSetAllPriority);
  SDL_LIBRARY_FIND(SDL_LogSetPriority);
  SDL_LIBRARY_FIND(SDL_LogGetPriority);
  SDL_LIBRARY_FIND(SDL_LogResetPriorities);
  SDL_LIBRARY_FIND(SDL_Log);
  SDL_LIBRARY_FIND(SDL_LogVerbose);
  SDL_LIBRARY_FIND(SDL_LogDebug);
  SDL_LIBRARY_FIND(SDL_LogInfo);
  SDL_LIBRARY_FIND(SDL_LogWarn);
  SDL_LIBRARY_FIND(SDL_LogError);
  SDL_LIBRARY_FIND(SDL_LogCritical);
  SDL_LIBRARY_FIND(SDL_LogMessage);
  SDL_LIBRARY_FIND(SDL_LogMessageV);
  SDL_LIBRARY_FIND(SDL_LogGetOutputFunction);
  SDL_LIBRARY_FIND(SDL_LogSetOutputFunction);
  SDL_LIBRARY_FIND(SDL_CreateMutex);
  SDL_LIBRARY_FIND(SDL_LockMutex);
  SDL_LIBRARY_FIND(SDL_TryLockMutex);
  SDL_LIBRARY_FIND(SDL_UnlockMutex);
  SDL_LIBRARY_FIND(SDL_DestroyMutex);
  SDL_LIBRARY_FIND(SDL_CreateSemaphore);
  SDL_LIBRARY_FIND(SDL_DestroySemaphore);
  SDL_LIBRARY_FIND(SDL_SemWait);
  SDL_LIBRARY_FIND(SDL_SemTryWait);
  SDL_LIBRARY_FIND(SDL_SemWaitTimeout);
  SDL_LIBRARY_FIND(SDL_SemPost);
  SDL_LIBRARY_FIND(SDL_SemValue);
  SDL_LIBRARY_FIND(SDL_CreateCond);
  SDL_LIBRARY_FIND(SDL_DestroyCond);
  SDL_LIBRARY_FIND(SDL_CondSignal);
  SDL_LIBRARY_FIND(SDL_CondBroadcast);
  SDL_LIBRARY_FIND(SDL_CondWait);
  SDL_LIBRARY_FIND(SDL_CondWaitTimeout);
  SDL_LIBRARY_FIND(SDL_CreateRGBSurface);
  SDL_LIBRARY_FIND(SDL_CreateRGBSurfaceFrom);
  SDL_LIBRARY_FIND(SDL_FreeSurface);
  SDL_LIBRARY_FIND(SDL_SetSurfacePalette);
  SDL_LIBRARY_FIND(SDL_LockSurface);
  SDL_LIBRARY_FIND(SDL_UnlockSurface);
  SDL_LIBRARY_FIND(SDL_LoadBMP_RW);
  SDL_LIBRARY_FIND(SDL_SaveBMP_RW);
  SDL_LIBRARY_FIND(SDL_SetSurfaceRLE);
  SDL_LIBRARY_FIND(SDL_SetColorKey);
  SDL_LIBRARY_FIND(SDL_GetColorKey);
  SDL_LIBRARY_FIND(SDL_SetSurfaceColorMod);
  SDL_LIBRARY_FIND(SDL_GetSurfaceColorMod);
  SDL_LIBRARY_FIND(SDL_SetSurfaceAlphaMod);
  SDL_LIBRARY_FIND(SDL_GetSurfaceAlphaMod);
  SDL_LIBRARY_FIND(SDL_SetSurfaceBlendMode);
  SDL_LIBRARY_FIND(SDL_GetSurfaceBlendMode);
  SDL_LIBRARY_FIND(SDL_SetClipRect);
  SDL_LIBRARY_FIND(SDL_GetClipRect);
  SDL_LIBRARY_FIND(SDL_ConvertSurface);
  SDL_LIBRARY_FIND(SDL_ConvertSurfaceFormat);
  SDL_LIBRARY_FIND(SDL_ConvertPixels);
  SDL_LIBRARY_FIND(SDL_FillRect);
  SDL_LIBRARY_FIND(SDL_FillRects);
  SDL_LIBRARY_FIND(SDL_UpperBlit);
  SDL_LIBRARY_FIND(SDL_LowerBlit);
  SDL_LIBRARY_FIND(SDL_SoftStretch);
  SDL_LIBRARY_FIND(SDL_UpperBlitScaled);
  SDL_LIBRARY_FIND(SDL_LowerBlitScaled);
  SDL_LIBRARY_FIND(SDL_PumpEvents);
  SDL_LIBRARY_FIND(SDL_PeepEvents);
  SDL_LIBRARY_FIND(SDL_HasEvent);
  SDL_LIBRARY_FIND(SDL_HasEvents);
  SDL_LIBRARY_FIND(SDL_FlushEvent);
  SDL_LIBRARY_FIND(SDL_FlushEvents);
  SDL_LIBRARY_FIND(SDL_PollEvent);
  SDL_LIBRARY_FIND(SDL_WaitEvent);
  SDL_LIBRARY_FIND(SDL_WaitEventTimeout);
  SDL_LIBRARY_FIND(SDL_PushEvent);
  SDL_LIBRARY_FIND(SDL_SetEventFilter);
  SDL_LIBRARY_FIND(SDL_GetEventFilter);
  SDL_LIBRARY_FIND(SDL_AddEventWatch);
  SDL_LIBRARY_FIND(SDL_DelEventWatch);
  SDL_LIBRARY_FIND(SDL_FilterEvents);
  SDL_LIBRARY_FIND(SDL_EventState);
  SDL_LIBRARY_FIND(SDL_RegisterEvents);
  SDL_LIBRARY_FIND(SDL_GetMouseFocus);
  SDL_LIBRARY_FIND(SDL_GetMouseState);
  SDL_LIBRARY_FIND(SDL_GetRelativeMouseState);
  SDL_LIBRARY_FIND(SDL_WarpMouseInWindow);
  SDL_LIBRARY_FIND(SDL_SetRelativeMouseMode);
  SDL_LIBRARY_FIND(SDL_GetRelativeMouseMode);
  SDL_LIBRARY_FIND(SDL_CreateCursor);
  SDL_LIBRARY_FIND(SDL_CreateColorCursor);
  SDL_LIBRARY_FIND(SDL_CreateSystemCursor);
  SDL_LIBRARY_FIND(SDL_SetCursor);
  SDL_LIBRARY_FIND(SDL_GetCursor);
  SDL_LIBRARY_FIND(SDL_GetDefaultCursor);
  SDL_LIBRARY_FIND(SDL_FreeCursor);
  SDL_LIBRARY_FIND(SDL_ShowCursor);
  SDL_LIBRARY_FIND(SDL_GetThreadName);
  SDL_LIBRARY_FIND(SDL_ThreadID);
  SDL_LIBRARY_FIND(SDL_GetThreadID);
  SDL_LIBRARY_FIND(SDL_SetThreadPriority);
  SDL_LIBRARY_FIND(SDL_WaitThread);
  SDL_LIBRARY_FIND(SDL_TLSCreate);
  SDL_LIBRARY_FIND(SDL_TLSGet);
  SDL_LIBRARY_FIND(SDL_TLSSet);
  SDL_LIBRARY_FIND(SDL_GetKeyboardFocus);
  SDL_LIBRARY_FIND(SDL_GetKeyboardState);
  SDL_LIBRARY_FIND(SDL_GetModState);
  SDL_LIBRARY_FIND(SDL_SetModState);
  SDL_LIBRARY_FIND(SDL_GetKeyFromScancode);
  SDL_LIBRARY_FIND(SDL_GetScancodeFromKey);
  SDL_LIBRARY_FIND(SDL_GetScancodeName);
  SDL_LIBRARY_FIND(SDL_GetScancodeFromName);
  SDL_LIBRARY_FIND(SDL_GetKeyName);
  SDL_LIBRARY_FIND(SDL_GetKeyFromName);
  SDL_LIBRARY_FIND(SDL_StartTextInput);
  SDL_LIBRARY_FIND(SDL_IsTextInputActive);
  SDL_LIBRARY_FIND(SDL_StopTextInput);
  SDL_LIBRARY_FIND(SDL_SetTextInputRect);
  SDL_LIBRARY_FIND(SDL_HasScreenKeyboardSupport);
  SDL_LIBRARY_FIND(SDL_IsScreenKeyboardShown);
  SDL_LIBRARY_FIND(SDL_GameControllerAddMapping);
  SDL_LIBRARY_FIND(SDL_GameControllerMappingForGUID);
  SDL_LIBRARY_FIND(SDL_GameControllerMapping);
  SDL_LIBRARY_FIND(SDL_IsGameController);
  SDL_LIBRARY_FIND(SDL_GameControllerNameForIndex);
  SDL_LIBRARY_FIND(SDL_GameControllerOpen);
  SDL_LIBRARY_FIND(SDL_GameControllerName);
  SDL_LIBRARY_FIND(SDL_GameControllerGetAttached);
  SDL_LIBRARY_FIND(SDL_GameControllerGetJoystick);
  SDL_LIBRARY_FIND(SDL_GameControllerEventState);
  SDL_LIBRARY_FIND(SDL_GameControllerUpdate);
  SDL_LIBRARY_FIND(SDL_GameControllerGetAxisFromString);
  SDL_LIBRARY_FIND(SDL_GameControllerGetButtonFromString);
  SDL_LIBRARY_FIND(SDL_GameControllerGetButton);
  SDL_LIBRARY_FIND(SDL_GameControllerClose);
  SDL_LIBRARY_FIND(SDL_GetNumAudioDrivers);
  SDL_LIBRARY_FIND(SDL_GetAudioDriver);
  SDL_LIBRARY_FIND(SDL_AudioInit);
  SDL_LIBRARY_FIND(SDL_AudioQuit);
  SDL_LIBRARY_FIND(SDL_GetCurrentAudioDriver);
  SDL_LIBRARY_FIND(SDL_OpenAudio);
  SDL_LIBRARY_FIND(SDL_GetNumAudioDevices);
  SDL_LIBRARY_FIND(SDL_GetAudioDeviceName);
  SDL_LIBRARY_FIND(SDL_OpenAudioDevice);
  SDL_LIBRARY_FIND(SDL_GetAudioStatus);
  SDL_LIBRARY_FIND(SDL_PauseAudio);
  SDL_LIBRARY_FIND(SDL_PauseAudioDevice);
  SDL_LIBRARY_FIND(SDL_LoadWAV_RW);
  SDL_LIBRARY_FIND(SDL_FreeWAV);
  SDL_LIBRARY_FIND(SDL_BuildAudioCVT);
  SDL_LIBRARY_FIND(SDL_ConvertAudio);
  SDL_LIBRARY_FIND(SDL_MixAudio);
  SDL_LIBRARY_FIND(SDL_MixAudioFormat);
  SDL_LIBRARY_FIND(SDL_LockAudio);
  SDL_LIBRARY_FIND(SDL_LockAudioDevice);
  SDL_LIBRARY_FIND(SDL_UnlockAudio);
  SDL_LIBRARY_FIND(SDL_UnlockAudioDevice);
  SDL_LIBRARY_FIND(SDL_CloseAudio);
  SDL_LIBRARY_FIND(SDL_CloseAudioDevice);
  SDL_LIBRARY_FIND(SDL_GetNumVideoDrivers);
  SDL_LIBRARY_FIND(SDL_GetVideoDriver);
  SDL_LIBRARY_FIND(SDL_VideoInit);
  SDL_LIBRARY_FIND(SDL_VideoQuit);
  SDL_LIBRARY_FIND(SDL_GetCurrentVideoDriver);
  SDL_LIBRARY_FIND(SDL_GetNumVideoDisplays);
  SDL_LIBRARY_FIND(SDL_GetDisplayName);
  SDL_LIBRARY_FIND(SDL_GetDisplayBounds);
  SDL_LIBRARY_FIND(SDL_GetNumDisplayModes);
  SDL_LIBRARY_FIND(SDL_GetDisplayMode);
  SDL_LIBRARY_FIND(SDL_GetDesktopDisplayMode);
  SDL_LIBRARY_FIND(SDL_GetCurrentDisplayMode);
  SDL_LIBRARY_FIND(SDL_GetClosestDisplayMode);
  SDL_LIBRARY_FIND(SDL_GetWindowDisplayIndex);
  SDL_LIBRARY_FIND(SDL_SetWindowDisplayMode);
  SDL_LIBRARY_FIND(SDL_GetWindowDisplayMode);
  SDL_LIBRARY_FIND(SDL_GetWindowPixelFormat);
  SDL_LIBRARY_FIND(SDL_CreateWindow);
  SDL_LIBRARY_FIND(SDL_CreateWindowFrom);
  SDL_LIBRARY_FIND(SDL_GetWindowID);
  SDL_LIBRARY_FIND(SDL_GetWindowFromID);
  SDL_LIBRARY_FIND(SDL_GetWindowFlags);
  SDL_LIBRARY_FIND(SDL_SetWindowTitle);
  SDL_LIBRARY_FIND(SDL_GetWindowTitle);
  SDL_LIBRARY_FIND(SDL_SetWindowIcon);
  SDL_LIBRARY_FIND(SDL_GetWindowData);
  SDL_LIBRARY_FIND(SDL_SetWindowPosition);
  SDL_LIBRARY_FIND(SDL_GetWindowPosition);
  SDL_LIBRARY_FIND(SDL_SetWindowSize);
  SDL_LIBRARY_FIND(SDL_GetWindowSize);
  SDL_LIBRARY_FIND(SDL_SetWindowMinimumSize);
  SDL_LIBRARY_FIND(SDL_GetWindowMinimumSize);
  SDL_LIBRARY_FIND(SDL_SetWindowMaximumSize);
  SDL_LIBRARY_FIND(SDL_GetWindowMaximumSize);
  SDL_LIBRARY_FIND(SDL_SetWindowBordered);
  SDL_LIBRARY_FIND(SDL_ShowWindow);
  SDL_LIBRARY_FIND(SDL_HideWindow);
  SDL_LIBRARY_FIND(SDL_RaiseWindow);
  SDL_LIBRARY_FIND(SDL_MaximizeWindow);
  SDL_LIBRARY_FIND(SDL_MinimizeWindow);
  SDL_LIBRARY_FIND(SDL_RestoreWindow);
  SDL_LIBRARY_FIND(SDL_SetWindowFullscreen);
  SDL_LIBRARY_FIND(SDL_GetWindowSurface);
  SDL_LIBRARY_FIND(SDL_UpdateWindowSurface);
  SDL_LIBRARY_FIND(SDL_UpdateWindowSurfaceRects);
  SDL_LIBRARY_FIND(SDL_SetWindowGrab);
  SDL_LIBRARY_FIND(SDL_GetWindowGrab);
  SDL_LIBRARY_FIND(SDL_SetWindowBrightness);
  SDL_LIBRARY_FIND(SDL_GetWindowBrightness);
  SDL_LIBRARY_FIND(SDL_SetWindowGammaRamp);
  SDL_LIBRARY_FIND(SDL_GetWindowGammaRamp);
  SDL_LIBRARY_FIND(SDL_DestroyWindow);
  SDL_LIBRARY_FIND(SDL_IsScreenSaverEnabled);
  SDL_LIBRARY_FIND(SDL_EnableScreenSaver);
  SDL_LIBRARY_FIND(SDL_DisableScreenSaver);
  SDL_LIBRARY_FIND(SDL_GL_LoadLibrary);
  SDL_LIBRARY_FIND(SDL_GL_GetProcAddress);
  SDL_LIBRARY_FIND(SDL_GL_UnloadLibrary);
  SDL_LIBRARY_FIND(SDL_GL_ExtensionSupported);
  SDL_LIBRARY_FIND(SDL_GL_SetAttribute);
  SDL_LIBRARY_FIND(SDL_GL_GetAttribute);
  SDL_LIBRARY_FIND(SDL_GL_CreateContext);
  SDL_LIBRARY_FIND(SDL_GL_MakeCurrent);
  SDL_LIBRARY_FIND(SDL_GL_GetCurrentContext);
  SDL_LIBRARY_FIND(SDL_GL_SetSwapInterval);
  SDL_LIBRARY_FIND(SDL_GL_GetSwapInterval);
  SDL_LIBRARY_FIND(SDL_GL_SwapWindow);
  SDL_LIBRARY_FIND(SDL_GL_DeleteContext);
  SDL_LIBRARY_FIND(SDL_RWFromFile);
  SDL_LIBRARY_FIND(SDL_RWFromFP);
  SDL_LIBRARY_FIND(SDL_RWFromFP);
  SDL_LIBRARY_FIND(SDL_RWFromMem);
  SDL_LIBRARY_FIND(SDL_RWFromConstMem);
  SDL_LIBRARY_FIND(SDL_AllocRW);
  SDL_LIBRARY_FIND(SDL_FreeRW);
  SDL_LIBRARY_FIND(SDL_ReadU8);
  SDL_LIBRARY_FIND(SDL_ReadLE16);
  SDL_LIBRARY_FIND(SDL_ReadBE16);
  SDL_LIBRARY_FIND(SDL_ReadLE32);
  SDL_LIBRARY_FIND(SDL_ReadBE32);
  SDL_LIBRARY_FIND(SDL_ReadLE64);
  SDL_LIBRARY_FIND(SDL_ReadBE64);
  SDL_LIBRARY_FIND(SDL_WriteU8);
  SDL_LIBRARY_FIND(SDL_WriteLE16);
  SDL_LIBRARY_FIND(SDL_WriteBE16);
  SDL_LIBRARY_FIND(SDL_WriteLE32);
  SDL_LIBRARY_FIND(SDL_WriteBE32);
  SDL_LIBRARY_FIND(SDL_WriteLE64);
  SDL_LIBRARY_FIND(SDL_WriteBE64);
  SDL_LIBRARY_FIND(SDL_Init);
  SDL_LIBRARY_FIND(SDL_InitSubSystem);
  SDL_LIBRARY_FIND(SDL_QuitSubSystem);
  SDL_LIBRARY_FIND(SDL_WasInit);
  SDL_LIBRARY_FIND(SDL_Quit);
  SDL_LIBRARY_FIND(SDL_GetVersion);
  SDL_LIBRARY_FIND(SDL_GetRevision);
  SDL_LIBRARY_FIND(SDL_GetRevisionNumber);
  SDL_LIBRARY_FIND(SDL_GetTicks);
  SDL_LIBRARY_FIND(SDL_GetPerformanceCounter);
  SDL_LIBRARY_FIND(SDL_GetPerformanceFrequency);
  SDL_LIBRARY_FIND(SDL_Delay);
  SDL_LIBRARY_FIND(SDL_AddTimer);
  SDL_LIBRARY_FIND(SDL_RemoveTimer);
  SDL_LIBRARY_FIND(SDL_SetHintWithPriority);
  SDL_LIBRARY_FIND(SDL_SetHint);
  SDL_LIBRARY_FIND(SDL_GetHint);
  SDL_LIBRARY_FIND(SDL_AddHintCallback);
  SDL_LIBRARY_FIND(SDL_DelHintCallback);
  SDL_LIBRARY_FIND(SDL_ClearHints);
  SDL_LIBRARY_FIND(SDL_NumJoysticks);
  SDL_LIBRARY_FIND(SDL_JoystickNameForIndex);
  SDL_LIBRARY_FIND(SDL_JoystickOpen);
  SDL_LIBRARY_FIND(SDL_JoystickName);
  SDL_LIBRARY_FIND(SDL_JoystickGetDeviceGUID);
  SDL_LIBRARY_FIND(SDL_JoystickGetGUID);
  SDL_LIBRARY_FIND(SDL_JoystickGetGUIDFromString);
  SDL_LIBRARY_FIND(SDL_JoystickGetAttached);
  SDL_LIBRARY_FIND(SDL_JoystickInstanceID);
  SDL_LIBRARY_FIND(SDL_JoystickNumAxes);
  SDL_LIBRARY_FIND(SDL_JoystickNumBalls);
  SDL_LIBRARY_FIND(SDL_JoystickNumHats);
  SDL_LIBRARY_FIND(SDL_JoystickNumButtons);
  SDL_LIBRARY_FIND(SDL_JoystickUpdate);
  SDL_LIBRARY_FIND(SDL_JoystickEventState);
  SDL_LIBRARY_FIND(SDL_JoystickGetAxis);
  SDL_LIBRARY_FIND(SDL_JoystickGetHat);
  SDL_LIBRARY_FIND(SDL_JoystickGetBall);
  SDL_LIBRARY_FIND(SDL_JoystickGetButton);
  SDL_LIBRARY_FIND(SDL_JoystickClose);
  SDL_LIBRARY_FIND(SDL_RecordGesture);
  SDL_LIBRARY_FIND(SDL_SaveAllDollarTemplates);
  SDL_LIBRARY_FIND(SDL_SaveDollarTemplate);
  SDL_LIBRARY_FIND(SDL_LoadDollarTemplates);
  SDL_LIBRARY_FIND(SDL_NumHaptics);
  SDL_LIBRARY_FIND(SDL_HapticName);
  SDL_LIBRARY_FIND(SDL_HapticOpen);
  SDL_LIBRARY_FIND(SDL_HapticOpened);
  SDL_LIBRARY_FIND(SDL_HapticIndex);
  SDL_LIBRARY_FIND(SDL_MouseIsHaptic);
  SDL_LIBRARY_FIND(SDL_HapticOpenFromMouse);
  SDL_LIBRARY_FIND(SDL_JoystickIsHaptic);
  SDL_LIBRARY_FIND(SDL_HapticOpenFromJoystick);
  SDL_LIBRARY_FIND(SDL_HapticClose);
  SDL_LIBRARY_FIND(SDL_HapticNumEffects);
  SDL_LIBRARY_FIND(SDL_HapticNumEffectsPlaying);
  SDL_LIBRARY_FIND(SDL_HapticNumAxes);
  SDL_LIBRARY_FIND(SDL_HapticEffectSupported);
  SDL_LIBRARY_FIND(SDL_HapticNewEffect);
  SDL_LIBRARY_FIND(SDL_HapticUpdateEffect);
  SDL_LIBRARY_FIND(SDL_HapticRunEffect);
  SDL_LIBRARY_FIND(SDL_HapticStopEffect);
  SDL_LIBRARY_FIND(SDL_HapticDestroyEffect);
  SDL_LIBRARY_FIND(SDL_HapticGetEffectStatus);
  SDL_LIBRARY_FIND(SDL_HapticSetGain);
  SDL_LIBRARY_FIND(SDL_HapticSetAutocenter);
  SDL_LIBRARY_FIND(SDL_HapticPause);
  SDL_LIBRARY_FIND(SDL_HapticUnpause);
  SDL_LIBRARY_FIND(SDL_HapticStopAll);
  SDL_LIBRARY_FIND(SDL_HapticRumbleSupported);
  SDL_LIBRARY_FIND(SDL_HapticRumbleInit);
  SDL_LIBRARY_FIND(SDL_HapticRumblePlay);
  SDL_LIBRARY_FIND(SDL_HapticRumbleStop);
  SDL_LIBRARY_FIND(SDL_ShowMessageBox);
  SDL_LIBRARY_FIND(SDL_ShowSimpleMessageBox);
  SDL_LIBRARY_FIND(SDL_PixelFormatEnumToMasks);
  SDL_LIBRARY_FIND(SDL_MasksToPixelFormatEnum);
  SDL_LIBRARY_FIND(SDL_AllocFormat);
  SDL_LIBRARY_FIND(SDL_FreeFormat);
  SDL_LIBRARY_FIND(SDL_AllocPalette);
  SDL_LIBRARY_FIND(SDL_SetPixelFormatPalette);
  SDL_LIBRARY_FIND(SDL_SetPaletteColors);
  SDL_LIBRARY_FIND(SDL_FreePalette);
  SDL_LIBRARY_FIND(SDL_MapRGB);
  SDL_LIBRARY_FIND(SDL_MapRGBA);
  SDL_LIBRARY_FIND(SDL_GetRGB);
  SDL_LIBRARY_FIND(SDL_GetRGBA);
  SDL_LIBRARY_FIND(SDL_CalculateGammaRamp);
  SDL_LIBRARY_FIND(SDL_GetPowerInfo);
  SDL_LIBRARY_FIND(SDL_GetCPUCount);
  SDL_LIBRARY_FIND(SDL_GetCPUCacheLineSize);
  SDL_LIBRARY_FIND(SDL_HasRDTSC);
  SDL_LIBRARY_FIND(SDL_HasAltiVec);
  SDL_LIBRARY_FIND(SDL_HasMMX);
  SDL_LIBRARY_FIND(SDL_Has3DNow);
  SDL_LIBRARY_FIND(SDL_HasSSE);
  SDL_LIBRARY_FIND(SDL_HasSSE2);
  SDL_LIBRARY_FIND(SDL_HasSSE3);
  SDL_LIBRARY_FIND(SDL_HasSSE41);
  SDL_LIBRARY_FIND(SDL_HasSSE42);
  SDL_LIBRARY_FIND(SDL_GetNumTouchDevices);
  SDL_LIBRARY_FIND(SDL_GetTouchDevice);
  SDL_LIBRARY_FIND(SDL_GetNumTouchFingers);
  SDL_LIBRARY_FIND(SDL_GetTouchFinger);
  SDL_LIBRARY_FIND(SDL_SetError);
  SDL_LIBRARY_FIND(SDL_GetError);
  SDL_LIBRARY_FIND(SDL_ClearError);
  SDL_LIBRARY_FIND(SDL_Error);
  SDL_LIBRARY_FIND(SDL_SetClipboardText);
  SDL_LIBRARY_FIND(SDL_GetClipboardText);
  SDL_LIBRARY_FIND(SDL_HasClipboardText);
  SDL_LIBRARY_FIND(SDL_GetWindowWMInfo);

  if (SDL_GetVersion == NULL) {
    result = SDLEW_ERROR_VERSION;
  }
  else {
    SDL_GetVersion(&version);
    if(version.major < 2) {
      result = SDLEW_ERROR_VERSION;
    }
    else {
      result = SDLEW_SUCCESS;
    }
  }

  return result;
}
