src/SDL.c
author Sylvain Becker <sylvain.becker@gmail.com>
Mon, 19 Aug 2019 21:23:47 +0200
changeset 13027 69cc269eec53
parent 12630 a26e3c61e35f
permissions -rw-r--r--
Fix audio conversion U16_to_F32_SSE2 (bug 4186)
     1 /*
     2   Simple DirectMedia Layer
     3   Copyright (C) 1997-2019 Sam Lantinga <slouken@libsdl.org>
     4 
     5   This software is provided 'as-is', without any express or implied
     6   warranty.  In no event will the authors be held liable for any damages
     7   arising from the use of this software.
     8 
     9   Permission is granted to anyone to use this software for any purpose,
    10   including commercial applications, and to alter it and redistribute it
    11   freely, subject to the following restrictions:
    12 
    13   1. The origin of this software must not be misrepresented; you must not
    14      claim that you wrote the original software. If you use this software
    15      in a product, an acknowledgment in the product documentation would be
    16      appreciated but is not required.
    17   2. Altered source versions must be plainly marked as such, and must not be
    18      misrepresented as being the original software.
    19   3. This notice may not be removed or altered from any source distribution.
    20 */
    21 #include "./SDL_internal.h"
    22 
    23 #if defined(__WIN32__)
    24 #include "core/windows/SDL_windows.h"
    25 #endif
    26 
    27 /* Initialization code for SDL */
    28 
    29 #include "SDL.h"
    30 #include "SDL_bits.h"
    31 #include "SDL_revision.h"
    32 #include "SDL_assert_c.h"
    33 #include "events/SDL_events_c.h"
    34 #include "haptic/SDL_haptic_c.h"
    35 #include "joystick/SDL_joystick_c.h"
    36 #include "sensor/SDL_sensor_c.h"
    37 
    38 /* Initialization/Cleanup routines */
    39 #if !SDL_TIMERS_DISABLED
    40 # include "timer/SDL_timer_c.h"
    41 #endif
    42 #if SDL_VIDEO_DRIVER_WINDOWS
    43 extern int SDL_HelperWindowCreate(void);
    44 extern int SDL_HelperWindowDestroy(void);
    45 #endif
    46 
    47 
    48 /* The initialized subsystems */
    49 #ifdef SDL_MAIN_NEEDED
    50 static SDL_bool SDL_MainIsReady = SDL_FALSE;
    51 #else
    52 static SDL_bool SDL_MainIsReady = SDL_TRUE;
    53 #endif
    54 static SDL_bool SDL_bInMainQuit = SDL_FALSE;
    55 static Uint8 SDL_SubsystemRefCount[ 32 ];
    56 
    57 /* Private helper to increment a subsystem's ref counter. */
    58 static void
    59 SDL_PrivateSubsystemRefCountIncr(Uint32 subsystem)
    60 {
    61     int subsystem_index = SDL_MostSignificantBitIndex32(subsystem);
    62     SDL_assert(SDL_SubsystemRefCount[subsystem_index] < 255);
    63     ++SDL_SubsystemRefCount[subsystem_index];
    64 }
    65 
    66 /* Private helper to decrement a subsystem's ref counter. */
    67 static void
    68 SDL_PrivateSubsystemRefCountDecr(Uint32 subsystem)
    69 {
    70     int subsystem_index = SDL_MostSignificantBitIndex32(subsystem);
    71     if (SDL_SubsystemRefCount[subsystem_index] > 0) {
    72         --SDL_SubsystemRefCount[subsystem_index];
    73     }
    74 }
    75 
    76 /* Private helper to check if a system needs init. */
    77 static SDL_bool
    78 SDL_PrivateShouldInitSubsystem(Uint32 subsystem)
    79 {
    80     int subsystem_index = SDL_MostSignificantBitIndex32(subsystem);
    81     SDL_assert(SDL_SubsystemRefCount[subsystem_index] < 255);
    82     return (SDL_SubsystemRefCount[subsystem_index] == 0) ? SDL_TRUE : SDL_FALSE;
    83 }
    84 
    85 /* Private helper to check if a system needs to be quit. */
    86 static SDL_bool
    87 SDL_PrivateShouldQuitSubsystem(Uint32 subsystem) {
    88     int subsystem_index = SDL_MostSignificantBitIndex32(subsystem);
    89     if (SDL_SubsystemRefCount[subsystem_index] == 0) {
    90       return SDL_FALSE;
    91     }
    92 
    93     /* If we're in SDL_Quit, we shut down every subsystem, even if refcount
    94      * isn't zero.
    95      */
    96     return (SDL_SubsystemRefCount[subsystem_index] == 1 || SDL_bInMainQuit) ? SDL_TRUE : SDL_FALSE;
    97 }
    98 
    99 void
   100 SDL_SetMainReady(void)
   101 {
   102     SDL_MainIsReady = SDL_TRUE;
   103 }
   104 
   105 int
   106 SDL_InitSubSystem(Uint32 flags)
   107 {
   108     if (!SDL_MainIsReady) {
   109         SDL_SetError("Application didn't initialize properly, did you include SDL_main.h in the file containing your main() function?");
   110         return -1;
   111     }
   112 
   113     /* Clear the error message */
   114     SDL_ClearError();
   115 
   116     if ((flags & SDL_INIT_GAMECONTROLLER)) {
   117         /* game controller implies joystick */
   118         flags |= SDL_INIT_JOYSTICK;
   119     }
   120 
   121     if ((flags & (SDL_INIT_VIDEO|SDL_INIT_JOYSTICK))) {
   122         /* video or joystick implies events */
   123         flags |= SDL_INIT_EVENTS;
   124     }
   125 
   126 #if SDL_VIDEO_DRIVER_WINDOWS
   127     if ((flags & (SDL_INIT_HAPTIC|SDL_INIT_JOYSTICK))) {
   128         if (SDL_HelperWindowCreate() < 0) {
   129             return -1;
   130         }
   131     }
   132 #endif
   133 
   134 #if !SDL_TIMERS_DISABLED
   135     SDL_TicksInit();
   136 #endif
   137 
   138     /* Initialize the event subsystem */
   139     if ((flags & SDL_INIT_EVENTS)) {
   140 #if !SDL_EVENTS_DISABLED
   141         if (SDL_PrivateShouldInitSubsystem(SDL_INIT_EVENTS)) {
   142             if (SDL_EventsInit() < 0) {
   143                 return (-1);
   144             }
   145         }
   146         SDL_PrivateSubsystemRefCountIncr(SDL_INIT_EVENTS);
   147 #else
   148         return SDL_SetError("SDL not built with events support");
   149 #endif
   150     }
   151 
   152     /* Initialize the timer subsystem */
   153     if ((flags & SDL_INIT_TIMER)){
   154 #if !SDL_TIMERS_DISABLED
   155         if (SDL_PrivateShouldInitSubsystem(SDL_INIT_TIMER)) {
   156             if (SDL_TimerInit() < 0) {
   157                 return (-1);
   158             }
   159         }
   160         SDL_PrivateSubsystemRefCountIncr(SDL_INIT_TIMER);
   161 #else
   162         return SDL_SetError("SDL not built with timer support");
   163 #endif
   164     }
   165 
   166     /* Initialize the video subsystem */
   167     if ((flags & SDL_INIT_VIDEO)){
   168 #if !SDL_VIDEO_DISABLED
   169         if (SDL_PrivateShouldInitSubsystem(SDL_INIT_VIDEO)) {
   170             if (SDL_VideoInit(NULL) < 0) {
   171                 return (-1);
   172             }
   173         }
   174         SDL_PrivateSubsystemRefCountIncr(SDL_INIT_VIDEO);
   175 #else
   176         return SDL_SetError("SDL not built with video support");
   177 #endif
   178     }
   179 
   180     /* Initialize the audio subsystem */
   181     if ((flags & SDL_INIT_AUDIO)){
   182 #if !SDL_AUDIO_DISABLED
   183         if (SDL_PrivateShouldInitSubsystem(SDL_INIT_AUDIO)) {
   184             if (SDL_AudioInit(NULL) < 0) {
   185                 return (-1);
   186             }
   187         }
   188         SDL_PrivateSubsystemRefCountIncr(SDL_INIT_AUDIO);
   189 #else
   190         return SDL_SetError("SDL not built with audio support");
   191 #endif
   192     }
   193 
   194     /* Initialize the joystick subsystem */
   195     if ((flags & SDL_INIT_JOYSTICK)){
   196 #if !SDL_JOYSTICK_DISABLED
   197         if (SDL_PrivateShouldInitSubsystem(SDL_INIT_JOYSTICK)) {
   198            if (SDL_JoystickInit() < 0) {
   199                return (-1);
   200            }
   201         }
   202         SDL_PrivateSubsystemRefCountIncr(SDL_INIT_JOYSTICK);
   203 #else
   204         return SDL_SetError("SDL not built with joystick support");
   205 #endif
   206     }
   207 
   208     if ((flags & SDL_INIT_GAMECONTROLLER)){
   209 #if !SDL_JOYSTICK_DISABLED
   210         if (SDL_PrivateShouldInitSubsystem(SDL_INIT_GAMECONTROLLER)) {
   211             if (SDL_GameControllerInit() < 0) {
   212                 return (-1);
   213             }
   214         }
   215         SDL_PrivateSubsystemRefCountIncr(SDL_INIT_GAMECONTROLLER);
   216 #else
   217         return SDL_SetError("SDL not built with joystick support");
   218 #endif
   219     }
   220 
   221     /* Initialize the haptic subsystem */
   222     if ((flags & SDL_INIT_HAPTIC)){
   223 #if !SDL_HAPTIC_DISABLED
   224         if (SDL_PrivateShouldInitSubsystem(SDL_INIT_HAPTIC)) {
   225             if (SDL_HapticInit() < 0) {
   226                 return (-1);
   227             }
   228         }
   229         SDL_PrivateSubsystemRefCountIncr(SDL_INIT_HAPTIC);
   230 #else
   231         return SDL_SetError("SDL not built with haptic (force feedback) support");
   232 #endif
   233     }
   234 
   235     /* Initialize the sensor subsystem */
   236     if ((flags & SDL_INIT_SENSOR)){
   237 #if !SDL_SENSOR_DISABLED
   238         if (SDL_PrivateShouldInitSubsystem(SDL_INIT_SENSOR)) {
   239             if (SDL_SensorInit() < 0) {
   240                 return (-1);
   241             }
   242         }
   243         SDL_PrivateSubsystemRefCountIncr(SDL_INIT_SENSOR);
   244 #else
   245         return SDL_SetError("SDL not built with sensor support");
   246 #endif
   247     }
   248 
   249     return (0);
   250 }
   251 
   252 int
   253 SDL_Init(Uint32 flags)
   254 {
   255     return SDL_InitSubSystem(flags);
   256 }
   257 
   258 void
   259 SDL_QuitSubSystem(Uint32 flags)
   260 {
   261     /* Shut down requested initialized subsystems */
   262 #if !SDL_SENSOR_DISABLED
   263     if ((flags & SDL_INIT_SENSOR)) {
   264         if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_SENSOR)) {
   265             SDL_SensorQuit();
   266         }
   267         SDL_PrivateSubsystemRefCountDecr(SDL_INIT_SENSOR);
   268     }
   269 #endif
   270 
   271 #if !SDL_JOYSTICK_DISABLED
   272     if ((flags & SDL_INIT_GAMECONTROLLER)) {
   273         /* game controller implies joystick */
   274         flags |= SDL_INIT_JOYSTICK;
   275 
   276         if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_GAMECONTROLLER)) {
   277             SDL_GameControllerQuit();
   278         }
   279         SDL_PrivateSubsystemRefCountDecr(SDL_INIT_GAMECONTROLLER);
   280     }
   281 
   282     if ((flags & SDL_INIT_JOYSTICK)) {
   283         /* joystick implies events */
   284         flags |= SDL_INIT_EVENTS;
   285 
   286         if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_JOYSTICK)) {
   287             SDL_JoystickQuit();
   288         }
   289         SDL_PrivateSubsystemRefCountDecr(SDL_INIT_JOYSTICK);
   290     }
   291 #endif
   292 
   293 #if !SDL_HAPTIC_DISABLED
   294     if ((flags & SDL_INIT_HAPTIC)) {
   295         if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_HAPTIC)) {
   296             SDL_HapticQuit();
   297         }
   298         SDL_PrivateSubsystemRefCountDecr(SDL_INIT_HAPTIC);
   299     }
   300 #endif
   301 
   302 #if !SDL_AUDIO_DISABLED
   303     if ((flags & SDL_INIT_AUDIO)) {
   304         if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_AUDIO)) {
   305             SDL_AudioQuit();
   306         }
   307         SDL_PrivateSubsystemRefCountDecr(SDL_INIT_AUDIO);
   308     }
   309 #endif
   310 
   311 #if !SDL_VIDEO_DISABLED
   312     if ((flags & SDL_INIT_VIDEO)) {
   313         /* video implies events */
   314         flags |= SDL_INIT_EVENTS;
   315 
   316         if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_VIDEO)) {
   317             SDL_VideoQuit();
   318         }
   319         SDL_PrivateSubsystemRefCountDecr(SDL_INIT_VIDEO);
   320     }
   321 #endif
   322 
   323 #if !SDL_TIMERS_DISABLED
   324     if ((flags & SDL_INIT_TIMER)) {
   325         if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_TIMER)) {
   326             SDL_TimerQuit();
   327         }
   328         SDL_PrivateSubsystemRefCountDecr(SDL_INIT_TIMER);
   329     }
   330 #endif
   331 
   332 #if !SDL_EVENTS_DISABLED
   333     if ((flags & SDL_INIT_EVENTS)) {
   334         if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_EVENTS)) {
   335             SDL_EventsQuit();
   336         }
   337         SDL_PrivateSubsystemRefCountDecr(SDL_INIT_EVENTS);
   338     }
   339 #endif
   340 }
   341 
   342 Uint32
   343 SDL_WasInit(Uint32 flags)
   344 {
   345     int i;
   346     int num_subsystems = SDL_arraysize(SDL_SubsystemRefCount);
   347     Uint32 initialized = 0;
   348 
   349     /* Fast path for checking one flag */
   350     if (SDL_HasExactlyOneBitSet32(flags)) {
   351         int subsystem_index = SDL_MostSignificantBitIndex32(flags);
   352         return SDL_SubsystemRefCount[subsystem_index] ? flags : 0;
   353     }
   354 
   355     if (!flags) {
   356         flags = SDL_INIT_EVERYTHING;
   357     }
   358 
   359     num_subsystems = SDL_min(num_subsystems, SDL_MostSignificantBitIndex32(flags) + 1);
   360 
   361     /* Iterate over each bit in flags, and check the matching subsystem. */
   362     for (i = 0; i < num_subsystems; ++i) {
   363         if ((flags & 1) && SDL_SubsystemRefCount[i] > 0) {
   364             initialized |= (1 << i);
   365         }
   366 
   367         flags >>= 1;
   368     }
   369 
   370     return initialized;
   371 }
   372 
   373 void
   374 SDL_Quit(void)
   375 {
   376     SDL_bInMainQuit = SDL_TRUE;
   377 
   378     /* Quit all subsystems */
   379 #if SDL_VIDEO_DRIVER_WINDOWS
   380     SDL_HelperWindowDestroy();
   381 #endif
   382     SDL_QuitSubSystem(SDL_INIT_EVERYTHING);
   383 
   384 #if !SDL_TIMERS_DISABLED
   385     SDL_TicksQuit();
   386 #endif
   387 
   388     SDL_ClearHints();
   389     SDL_AssertionsQuit();
   390     SDL_LogResetPriorities();
   391 
   392     /* Now that every subsystem has been quit, we reset the subsystem refcount
   393      * and the list of initialized subsystems.
   394      */
   395     SDL_memset( SDL_SubsystemRefCount, 0x0, sizeof(SDL_SubsystemRefCount) );
   396 
   397     SDL_bInMainQuit = SDL_FALSE;
   398 }
   399 
   400 /* Get the library version number */
   401 void
   402 SDL_GetVersion(SDL_version * ver)
   403 {
   404     SDL_VERSION(ver);
   405 }
   406 
   407 /* Get the library source revision */
   408 const char *
   409 SDL_GetRevision(void)
   410 {
   411     return SDL_REVISION;
   412 }
   413 
   414 /* Get the library source revision number */
   415 int
   416 SDL_GetRevisionNumber(void)
   417 {
   418     return SDL_REVISION_NUMBER;
   419 }
   420 
   421 /* Get the name of the platform */
   422 const char *
   423 SDL_GetPlatform()
   424 {
   425 #if __AIX__
   426     return "AIX";
   427 #elif __ANDROID__
   428     return "Android";
   429 #elif __BSDI__
   430     return "BSDI";
   431 #elif __DREAMCAST__
   432     return "Dreamcast";
   433 #elif __EMSCRIPTEN__
   434     return "Emscripten";
   435 #elif __FREEBSD__
   436     return "FreeBSD";
   437 #elif __HAIKU__
   438     return "Haiku";
   439 #elif __HPUX__
   440     return "HP-UX";
   441 #elif __IRIX__
   442     return "Irix";
   443 #elif __LINUX__
   444     return "Linux";
   445 #elif __MINT__
   446     return "Atari MiNT";
   447 #elif __MACOS__
   448     return "MacOS Classic";
   449 #elif __MACOSX__
   450     return "Mac OS X";
   451 #elif __NACL__
   452     return "NaCl";
   453 #elif __NETBSD__
   454     return "NetBSD";
   455 #elif __OPENBSD__
   456     return "OpenBSD";
   457 #elif __OS2__
   458     return "OS/2";
   459 #elif __OSF__
   460     return "OSF/1";
   461 #elif __QNXNTO__
   462     return "QNX Neutrino";
   463 #elif __RISCOS__
   464     return "RISC OS";
   465 #elif __SOLARIS__
   466     return "Solaris";
   467 #elif __WIN32__
   468     return "Windows";
   469 #elif __WINRT__
   470     return "WinRT";
   471 #elif __TVOS__
   472     return "tvOS";
   473 #elif __IPHONEOS__
   474     return "iOS";
   475 #elif __PSP__
   476     return "PlayStation Portable";
   477 #else
   478     return "Unknown (see SDL_platform.h)";
   479 #endif
   480 }
   481 
   482 SDL_bool
   483 SDL_IsTablet()
   484 {
   485 #if __ANDROID__
   486     extern SDL_bool SDL_IsAndroidTablet(void);
   487     return SDL_IsAndroidTablet();
   488 #elif __IPHONEOS__
   489     extern SDL_bool SDL_IsIPad(void);
   490     return SDL_IsIPad();
   491 #else
   492     return SDL_FALSE;
   493 #endif
   494 }
   495 
   496 #if defined(__WIN32__)
   497 
   498 #if (!defined(HAVE_LIBC) || defined(__WATCOMC__)) && !defined(SDL_STATIC_LIB)
   499 /* Need to include DllMain() on Watcom C for some reason.. */
   500 
   501 BOOL APIENTRY
   502 _DllMainCRTStartup(HANDLE hModule,
   503                    DWORD ul_reason_for_call, LPVOID lpReserved)
   504 {
   505     switch (ul_reason_for_call) {
   506     case DLL_PROCESS_ATTACH:
   507     case DLL_THREAD_ATTACH:
   508     case DLL_THREAD_DETACH:
   509     case DLL_PROCESS_DETACH:
   510         break;
   511     }
   512     return TRUE;
   513 }
   514 #endif /* Building DLL */
   515 
   516 #endif /* __WIN32__ */
   517 
   518 /* vi: set sts=4 ts=4 sw=4 expandtab: */