src/SDL.c
author Sam Lantinga <slouken@libsdl.org>
Thu, 07 Dec 2017 16:08:47 -0800
changeset 11731 30f337dc8c74
parent 10955 82bec2d58a45
child 11811 5d94cb6b24d3
permissions -rw-r--r--
Added iOS and OSX versions of the Metal shaders
     1 /*
     2   Simple DirectMedia Layer
     3   Copyright (C) 1997-2017 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 
    37 /* Initialization/Cleanup routines */
    38 #if !SDL_TIMERS_DISABLED
    39 # include "timer/SDL_timer_c.h"
    40 #endif
    41 #if SDL_VIDEO_DRIVER_WINDOWS
    42 extern int SDL_HelperWindowCreate(void);
    43 extern int SDL_HelperWindowDestroy(void);
    44 #endif
    45 
    46 
    47 /* The initialized subsystems */
    48 #ifdef SDL_MAIN_NEEDED
    49 static SDL_bool SDL_MainIsReady = SDL_FALSE;
    50 #else
    51 static SDL_bool SDL_MainIsReady = SDL_TRUE;
    52 #endif
    53 static SDL_bool SDL_bInMainQuit = SDL_FALSE;
    54 static Uint8 SDL_SubsystemRefCount[ 32 ];
    55 
    56 /* Private helper to increment a subsystem's ref counter. */
    57 static void
    58 SDL_PrivateSubsystemRefCountIncr(Uint32 subsystem)
    59 {
    60     int subsystem_index = SDL_MostSignificantBitIndex32(subsystem);
    61     SDL_assert(SDL_SubsystemRefCount[subsystem_index] < 255);
    62     ++SDL_SubsystemRefCount[subsystem_index];
    63 }
    64 
    65 /* Private helper to decrement a subsystem's ref counter. */
    66 static void
    67 SDL_PrivateSubsystemRefCountDecr(Uint32 subsystem)
    68 {
    69     int subsystem_index = SDL_MostSignificantBitIndex32(subsystem);
    70     if (SDL_SubsystemRefCount[subsystem_index] > 0) {
    71         --SDL_SubsystemRefCount[subsystem_index];
    72     }
    73 }
    74 
    75 /* Private helper to check if a system needs init. */
    76 static SDL_bool
    77 SDL_PrivateShouldInitSubsystem(Uint32 subsystem)
    78 {
    79     int subsystem_index = SDL_MostSignificantBitIndex32(subsystem);
    80     SDL_assert(SDL_SubsystemRefCount[subsystem_index] < 255);
    81     return (SDL_SubsystemRefCount[subsystem_index] == 0) ? SDL_TRUE : SDL_FALSE;
    82 }
    83 
    84 /* Private helper to check if a system needs to be quit. */
    85 static SDL_bool
    86 SDL_PrivateShouldQuitSubsystem(Uint32 subsystem) {
    87     int subsystem_index = SDL_MostSignificantBitIndex32(subsystem);
    88     if (SDL_SubsystemRefCount[subsystem_index] == 0) {
    89       return SDL_FALSE;
    90     }
    91 
    92     /* If we're in SDL_Quit, we shut down every subsystem, even if refcount
    93      * isn't zero.
    94      */
    95     return (SDL_SubsystemRefCount[subsystem_index] == 1 || SDL_bInMainQuit) ? SDL_TRUE : SDL_FALSE;
    96 }
    97 
    98 void
    99 SDL_SetMainReady(void)
   100 {
   101     SDL_MainIsReady = SDL_TRUE;
   102 }
   103 
   104 int
   105 SDL_InitSubSystem(Uint32 flags)
   106 {
   107     if (!SDL_MainIsReady) {
   108         SDL_SetError("Application didn't initialize properly, did you include SDL_main.h in the file containing your main() function?");
   109         return -1;
   110     }
   111 
   112     /* Clear the error message */
   113     SDL_ClearError();
   114 
   115     if ((flags & SDL_INIT_GAMECONTROLLER)) {
   116         /* game controller implies joystick */
   117         flags |= SDL_INIT_JOYSTICK;
   118     }
   119 
   120     if ((flags & (SDL_INIT_VIDEO|SDL_INIT_JOYSTICK))) {
   121         /* video or joystick implies events */
   122         flags |= SDL_INIT_EVENTS;
   123     }
   124 
   125 #if SDL_VIDEO_DRIVER_WINDOWS
   126 	if ((flags & (SDL_INIT_HAPTIC|SDL_INIT_JOYSTICK))) {
   127 		if (SDL_HelperWindowCreate() < 0) {
   128 			return -1;
   129 		}
   130 	}
   131 #endif
   132 
   133 #if !SDL_TIMERS_DISABLED
   134     SDL_TicksInit();
   135 #endif
   136 
   137     /* Initialize the event subsystem */
   138     if ((flags & SDL_INIT_EVENTS)) {
   139 #if !SDL_EVENTS_DISABLED
   140         if (SDL_PrivateShouldInitSubsystem(SDL_INIT_EVENTS)) {
   141             if (SDL_StartEventLoop() < 0) {
   142                 return (-1);
   143             }
   144             SDL_QuitInit();
   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     return (0);
   236 }
   237 
   238 int
   239 SDL_Init(Uint32 flags)
   240 {
   241     return SDL_InitSubSystem(flags);
   242 }
   243 
   244 void
   245 SDL_QuitSubSystem(Uint32 flags)
   246 {
   247     /* Shut down requested initialized subsystems */
   248 #if !SDL_JOYSTICK_DISABLED
   249     if ((flags & SDL_INIT_GAMECONTROLLER)) {
   250         /* game controller implies joystick */
   251         flags |= SDL_INIT_JOYSTICK;
   252 
   253         if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_GAMECONTROLLER)) {
   254             SDL_GameControllerQuit();
   255         }
   256         SDL_PrivateSubsystemRefCountDecr(SDL_INIT_GAMECONTROLLER);
   257     }
   258 
   259     if ((flags & SDL_INIT_JOYSTICK)) {
   260         /* joystick implies events */
   261         flags |= SDL_INIT_EVENTS;
   262 
   263         if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_JOYSTICK)) {
   264             SDL_JoystickQuit();
   265         }
   266         SDL_PrivateSubsystemRefCountDecr(SDL_INIT_JOYSTICK);
   267     }
   268 #endif
   269 
   270 #if !SDL_HAPTIC_DISABLED
   271     if ((flags & SDL_INIT_HAPTIC)) {
   272         if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_HAPTIC)) {
   273             SDL_HapticQuit();
   274         }
   275         SDL_PrivateSubsystemRefCountDecr(SDL_INIT_HAPTIC);
   276     }
   277 #endif
   278 
   279 #if !SDL_AUDIO_DISABLED
   280     if ((flags & SDL_INIT_AUDIO)) {
   281         if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_AUDIO)) {
   282             SDL_AudioQuit();
   283         }
   284         SDL_PrivateSubsystemRefCountDecr(SDL_INIT_AUDIO);
   285     }
   286 #endif
   287 
   288 #if !SDL_VIDEO_DISABLED
   289     if ((flags & SDL_INIT_VIDEO)) {
   290         /* video implies events */
   291         flags |= SDL_INIT_EVENTS;
   292 
   293         if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_VIDEO)) {
   294             SDL_VideoQuit();
   295         }
   296         SDL_PrivateSubsystemRefCountDecr(SDL_INIT_VIDEO);
   297     }
   298 #endif
   299 
   300 #if !SDL_TIMERS_DISABLED
   301     if ((flags & SDL_INIT_TIMER)) {
   302         if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_TIMER)) {
   303             SDL_TimerQuit();
   304         }
   305         SDL_PrivateSubsystemRefCountDecr(SDL_INIT_TIMER);
   306     }
   307 #endif
   308 
   309 #if !SDL_EVENTS_DISABLED
   310     if ((flags & SDL_INIT_EVENTS)) {
   311         if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_EVENTS)) {
   312             SDL_QuitQuit();
   313             SDL_StopEventLoop();
   314         }
   315         SDL_PrivateSubsystemRefCountDecr(SDL_INIT_EVENTS);
   316     }
   317 #endif
   318 }
   319 
   320 Uint32
   321 SDL_WasInit(Uint32 flags)
   322 {
   323     int i;
   324     int num_subsystems = SDL_arraysize(SDL_SubsystemRefCount);
   325     Uint32 initialized = 0;
   326 
   327     if (!flags) {
   328         flags = SDL_INIT_EVERYTHING;
   329     }
   330 
   331     num_subsystems = SDL_min(num_subsystems, SDL_MostSignificantBitIndex32(flags) + 1);
   332 
   333     /* Iterate over each bit in flags, and check the matching subsystem. */
   334     for (i = 0; i < num_subsystems; ++i) {
   335         if ((flags & 1) && SDL_SubsystemRefCount[i] > 0) {
   336             initialized |= (1 << i);
   337         }
   338 
   339         flags >>= 1;
   340     }
   341 
   342     return initialized;
   343 }
   344 
   345 void
   346 SDL_Quit(void)
   347 {
   348     SDL_bInMainQuit = SDL_TRUE;
   349 
   350     /* Quit all subsystems */
   351 #if SDL_VIDEO_DRIVER_WINDOWS
   352     SDL_HelperWindowDestroy();
   353 #endif
   354     SDL_QuitSubSystem(SDL_INIT_EVERYTHING);
   355 
   356 #if !SDL_TIMERS_DISABLED
   357     SDL_TicksQuit();
   358 #endif
   359 
   360     SDL_ClearHints();
   361     SDL_AssertionsQuit();
   362     SDL_LogResetPriorities();
   363 
   364     /* Now that every subsystem has been quit, we reset the subsystem refcount
   365      * and the list of initialized subsystems.
   366      */
   367     SDL_memset( SDL_SubsystemRefCount, 0x0, sizeof(SDL_SubsystemRefCount) );
   368 
   369     SDL_bInMainQuit = SDL_FALSE;
   370 }
   371 
   372 /* Get the library version number */
   373 void
   374 SDL_GetVersion(SDL_version * ver)
   375 {
   376     SDL_VERSION(ver);
   377 }
   378 
   379 /* Get the library source revision */
   380 const char *
   381 SDL_GetRevision(void)
   382 {
   383     return SDL_REVISION;
   384 }
   385 
   386 /* Get the library source revision number */
   387 int
   388 SDL_GetRevisionNumber(void)
   389 {
   390     return SDL_REVISION_NUMBER;
   391 }
   392 
   393 /* Get the name of the platform */
   394 const char *
   395 SDL_GetPlatform()
   396 {
   397 #if __AIX__
   398     return "AIX";
   399 #elif __ANDROID__
   400     return "Android";
   401 #elif __BSDI__
   402     return "BSDI";
   403 #elif __DREAMCAST__
   404     return "Dreamcast";
   405 #elif __EMSCRIPTEN__
   406     return "Emscripten";
   407 #elif __FREEBSD__
   408     return "FreeBSD";
   409 #elif __HAIKU__
   410     return "Haiku";
   411 #elif __HPUX__
   412     return "HP-UX";
   413 #elif __IRIX__
   414     return "Irix";
   415 #elif __LINUX__
   416     return "Linux";
   417 #elif __MINT__
   418     return "Atari MiNT";
   419 #elif __MACOS__
   420     return "MacOS Classic";
   421 #elif __MACOSX__
   422     return "Mac OS X";
   423 #elif __NACL__
   424     return "NaCl";
   425 #elif __NETBSD__
   426     return "NetBSD";
   427 #elif __OPENBSD__
   428     return "OpenBSD";
   429 #elif __OS2__
   430     return "OS/2";
   431 #elif __OSF__
   432     return "OSF/1";
   433 #elif __QNXNTO__
   434     return "QNX Neutrino";
   435 #elif __RISCOS__
   436     return "RISC OS";
   437 #elif __SOLARIS__
   438     return "Solaris";
   439 #elif __WIN32__
   440     return "Windows";
   441 #elif __WINRT__
   442     return "WinRT";
   443 #elif __TVOS__
   444     return "tvOS";
   445 #elif __IPHONEOS__
   446     return "iOS";
   447 #elif __PSP__
   448     return "PlayStation Portable";
   449 #else
   450     return "Unknown (see SDL_platform.h)";
   451 #endif
   452 }
   453 
   454 #if defined(__WIN32__)
   455 
   456 #if !defined(HAVE_LIBC) || (defined(__WATCOMC__) && defined(BUILD_DLL))
   457 /* Need to include DllMain() on Watcom C for some reason.. */
   458 
   459 BOOL APIENTRY
   460 _DllMainCRTStartup(HANDLE hModule,
   461                    DWORD ul_reason_for_call, LPVOID lpReserved)
   462 {
   463     switch (ul_reason_for_call) {
   464     case DLL_PROCESS_ATTACH:
   465     case DLL_THREAD_ATTACH:
   466     case DLL_THREAD_DETACH:
   467     case DLL_PROCESS_DETACH:
   468         break;
   469     }
   470     return TRUE;
   471 }
   472 #endif /* building DLL with Watcom C */
   473 
   474 #endif /* __WIN32__ */
   475 
   476 /* vi: set sts=4 ts=4 sw=4 expandtab: */