src/SDL.c
author Ryan C. Gordon <icculus@icculus.org>
Wed, 07 Aug 2013 11:00:44 -0700
changeset 7588 f1ca6adffc4b
parent 7360 b86947ea2749
child 7589 e9a7333d86f0
permissions -rw-r--r--
Removed SDL_AssertionsInit(). It's a no-op, let's keep it that way. :)
     1 /*
     2   Simple DirectMedia Layer
     3   Copyright (C) 1997-2013 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_config.h"
    22 
    23 /* Initialization code for SDL */
    24 
    25 #include "SDL.h"
    26 #include "SDL_bits.h"
    27 #include "SDL_revision.h"
    28 #include "SDL_fatal.h"
    29 #include "SDL_assert_c.h"
    30 #include "events/SDL_events_c.h"
    31 #include "haptic/SDL_haptic_c.h"
    32 #include "joystick/SDL_joystick_c.h"
    33 
    34 /* Initialization/Cleanup routines */
    35 #if !SDL_TIMERS_DISABLED
    36 extern int SDL_TimerInit(void);
    37 extern void SDL_TimerQuit(void);
    38 extern void SDL_InitTicks(void);
    39 #endif
    40 #if SDL_VIDEO_DRIVER_WINDOWS
    41 extern int SDL_HelperWindowCreate(void);
    42 extern int SDL_HelperWindowDestroy(void);
    43 #endif
    44 
    45 
    46 /* The initialized subsystems */
    47 #ifdef SDL_MAIN_NEEDED
    48 static SDL_bool SDL_MainIsReady = SDL_FALSE;
    49 #else
    50 static SDL_bool SDL_MainIsReady = SDL_TRUE;
    51 #endif
    52 static SDL_bool SDL_bInMainQuit = SDL_FALSE;
    53 static Uint8 SDL_SubsystemRefCount[ 32 ];
    54 
    55 /* Private helper to increment a subsystem's ref counter. */
    56 static void
    57 SDL_PrivateSubsystemRefCountIncr(Uint32 subsystem)
    58 {
    59     int subsystem_index = SDL_MostSignificantBitIndex32(subsystem);
    60     SDL_assert(SDL_SubsystemRefCount[subsystem_index] < 255);
    61     ++SDL_SubsystemRefCount[subsystem_index];
    62 }
    63 
    64 /* Private helper to decrement a subsystem's ref counter. */
    65 static void
    66 SDL_PrivateSubsystemRefCountDecr(Uint32 subsystem)
    67 {
    68     int subsystem_index = SDL_MostSignificantBitIndex32(subsystem);
    69     if (SDL_SubsystemRefCount[subsystem_index] > 0) {
    70         --SDL_SubsystemRefCount[subsystem_index];
    71     }
    72 }
    73 
    74 /* Private helper to check if a system needs init. */
    75 static SDL_bool
    76 SDL_PrivateShouldInitSubsystem(Uint32 subsystem)
    77 {
    78     int subsystem_index = SDL_MostSignificantBitIndex32(subsystem);
    79     SDL_assert(SDL_SubsystemRefCount[subsystem_index] < 255);
    80     return (SDL_SubsystemRefCount[subsystem_index] == 0);
    81 }
    82 
    83 /* Private helper to check if a system needs to be quit. */
    84 static SDL_bool
    85 SDL_PrivateShouldQuitSubsystem(Uint32 subsystem) {
    86     int subsystem_index = SDL_MostSignificantBitIndex32(subsystem);
    87     if (SDL_SubsystemRefCount[subsystem_index] == 0) {
    88       return SDL_FALSE;
    89     }
    90 
    91     /* If we're in SDL_Quit, we shut down every subsystem, even if refcount
    92      * isn't zero.
    93      */
    94     return SDL_SubsystemRefCount[subsystem_index] == 1 || SDL_bInMainQuit;
    95 }
    96 
    97 void
    98 SDL_SetMainReady(void)
    99 {
   100     SDL_MainIsReady = SDL_TRUE;
   101 }
   102 
   103 int
   104 SDL_InitSubSystem(Uint32 flags)
   105 {
   106     if (!SDL_MainIsReady) {
   107         SDL_SetError("Application didn't initialize properly, did you include SDL_main.h in the file containing your main() function?");
   108         return -1;
   109     }
   110 
   111 #if !SDL_TIMERS_DISABLED
   112     SDL_InitTicks();
   113 #endif
   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     /* Initialize the event subsystem */
   126     if ((flags & SDL_INIT_EVENTS)) {
   127 #if !SDL_EVENTS_DISABLED
   128         if (SDL_PrivateShouldInitSubsystem(SDL_INIT_EVENTS)) {
   129             if (SDL_StartEventLoop() < 0) {
   130                 return (-1);
   131             }
   132             SDL_QuitInit();
   133         }
   134         SDL_PrivateSubsystemRefCountIncr(SDL_INIT_EVENTS);
   135 #else
   136         return SDL_SetError("SDL not built with events support");
   137 #endif
   138     }
   139 
   140     /* Initialize the timer subsystem */
   141     if ((flags & SDL_INIT_TIMER)){
   142 #if !SDL_TIMERS_DISABLED
   143         if (SDL_PrivateShouldInitSubsystem(SDL_INIT_TIMER)) {
   144             if (SDL_TimerInit() < 0) {
   145                 return (-1);
   146             }
   147         }
   148         SDL_PrivateSubsystemRefCountIncr(SDL_INIT_TIMER);
   149 #else
   150         return SDL_SetError("SDL not built with timer support");
   151 #endif
   152     }
   153 
   154     /* Initialize the video subsystem */
   155     if ((flags & SDL_INIT_VIDEO)){
   156 #if !SDL_VIDEO_DISABLED
   157         if (SDL_PrivateShouldInitSubsystem(SDL_INIT_VIDEO)) {
   158             if (SDL_VideoInit(NULL) < 0) {
   159                 return (-1);
   160             }
   161         }
   162         SDL_PrivateSubsystemRefCountIncr(SDL_INIT_VIDEO);
   163 #else
   164         return SDL_SetError("SDL not built with video support");
   165 #endif
   166     }
   167 
   168     /* Initialize the audio subsystem */
   169     if ((flags & SDL_INIT_AUDIO)){
   170 #if !SDL_AUDIO_DISABLED
   171         if (SDL_PrivateShouldInitSubsystem(SDL_INIT_AUDIO)) {
   172             if (SDL_AudioInit(NULL) < 0) {
   173                 return (-1);
   174             }
   175         }
   176         SDL_PrivateSubsystemRefCountIncr(SDL_INIT_AUDIO);
   177 #else
   178         return SDL_SetError("SDL not built with audio support");
   179 #endif
   180     }
   181 
   182     /* Initialize the joystick subsystem */
   183     if ((flags & SDL_INIT_JOYSTICK)){
   184 #if !SDL_JOYSTICK_DISABLED
   185         if (SDL_PrivateShouldInitSubsystem(SDL_INIT_JOYSTICK)) {
   186            if (SDL_JoystickInit() < 0) {
   187                return (-1);
   188            }
   189         }
   190         SDL_PrivateSubsystemRefCountIncr(SDL_INIT_JOYSTICK);
   191 #else
   192         return SDL_SetError("SDL not built with joystick support");
   193 #endif
   194     }
   195 
   196     if ((flags & SDL_INIT_GAMECONTROLLER)){
   197 #if !SDL_JOYSTICK_DISABLED
   198         if (SDL_PrivateShouldInitSubsystem(SDL_INIT_GAMECONTROLLER)) {
   199             if (SDL_GameControllerInit() < 0) {
   200                 return (-1);
   201             }
   202         }
   203         SDL_PrivateSubsystemRefCountIncr(SDL_INIT_GAMECONTROLLER);
   204 #else
   205         return SDL_SetError("SDL not built with joystick support");
   206 #endif
   207     }
   208 
   209     /* Initialize the haptic subsystem */
   210     if ((flags & SDL_INIT_HAPTIC)){
   211 #if !SDL_HAPTIC_DISABLED
   212         if (SDL_PrivateShouldInitSubsystem(SDL_INIT_HAPTIC)) {
   213             if (SDL_HapticInit() < 0) {
   214                 return (-1);
   215             }
   216         }
   217         SDL_PrivateSubsystemRefCountIncr(SDL_INIT_HAPTIC);
   218 #else
   219         return SDL_SetError("SDL not built with haptic (force feedback) support");
   220 #endif
   221     }
   222 
   223     return (0);
   224 }
   225 
   226 int
   227 SDL_Init(Uint32 flags)
   228 {
   229     /* Clear the error message */
   230     SDL_ClearError();
   231 
   232 #if SDL_VIDEO_DRIVER_WINDOWS
   233     if (SDL_HelperWindowCreate() < 0) {
   234         return -1;
   235     }
   236 #endif
   237 
   238     /* Initialize the desired subsystems */
   239     if (SDL_InitSubSystem(flags) < 0) {
   240         return (-1);
   241     }
   242 
   243     /* Everything is initialized */
   244     if (!(flags & SDL_INIT_NOPARACHUTE)) {
   245         SDL_InstallParachute();
   246     }
   247 
   248     return (0);
   249 }
   250 
   251 void
   252 SDL_QuitSubSystem(Uint32 flags)
   253 {
   254     /* Shut down requested initialized subsystems */
   255 #if !SDL_JOYSTICK_DISABLED
   256     if ((flags & SDL_INIT_GAMECONTROLLER)) {
   257         /* game controller implies joystick */
   258         flags |= SDL_INIT_JOYSTICK;
   259 
   260         if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_GAMECONTROLLER)) {
   261             SDL_GameControllerQuit();
   262         }
   263         SDL_PrivateSubsystemRefCountDecr(SDL_INIT_GAMECONTROLLER);
   264     }
   265 
   266     if ((flags & SDL_INIT_JOYSTICK)) {
   267         /* joystick implies events */
   268         flags |= SDL_INIT_EVENTS;
   269 
   270         if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_JOYSTICK)) {
   271             SDL_JoystickQuit();
   272         }
   273         SDL_PrivateSubsystemRefCountDecr(SDL_INIT_JOYSTICK);
   274     }
   275 #endif
   276 
   277 #if !SDL_HAPTIC_DISABLED
   278     if ((flags & SDL_INIT_HAPTIC)) {
   279         if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_HAPTIC)) {
   280             SDL_HapticQuit();
   281         }
   282         SDL_PrivateSubsystemRefCountDecr(SDL_INIT_HAPTIC);
   283     }
   284 #endif
   285 
   286 #if !SDL_AUDIO_DISABLED
   287     if ((flags & SDL_INIT_AUDIO)) {
   288         if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_AUDIO)) {
   289             SDL_AudioQuit();
   290         }
   291         SDL_PrivateSubsystemRefCountDecr(SDL_INIT_AUDIO);
   292     }
   293 #endif
   294 
   295 #if !SDL_VIDEO_DISABLED
   296     if ((flags & SDL_INIT_VIDEO)) {
   297         /* video implies events */
   298         flags |= SDL_INIT_EVENTS;
   299 
   300         if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_VIDEO)) {
   301             SDL_VideoQuit();
   302         }
   303         SDL_PrivateSubsystemRefCountDecr(SDL_INIT_VIDEO);
   304     }
   305 #endif
   306 
   307 #if !SDL_TIMERS_DISABLED
   308     if ((flags & SDL_INIT_TIMER)) {
   309         if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_TIMER)) {
   310             SDL_TimerQuit();
   311         }
   312         SDL_PrivateSubsystemRefCountDecr(SDL_INIT_TIMER);
   313     }
   314 #endif
   315 
   316 #if !SDL_EVENTS_DISABLED
   317     if ((flags & SDL_INIT_EVENTS)) {
   318         if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_EVENTS)) {
   319             SDL_QuitQuit();
   320             SDL_StopEventLoop();
   321         }
   322         SDL_PrivateSubsystemRefCountDecr(SDL_INIT_EVENTS);
   323     }
   324 #endif
   325 }
   326 
   327 Uint32
   328 SDL_WasInit(Uint32 flags)
   329 {
   330     int i;
   331     int num_subsystems = SDL_arraysize(SDL_SubsystemRefCount);
   332     Uint32 initialized = 0;
   333 
   334     if (!flags) {
   335         flags = SDL_INIT_EVERYTHING;
   336     }
   337 
   338     num_subsystems = SDL_min(num_subsystems, SDL_MostSignificantBitIndex32(flags) + 1);
   339 
   340     /* Iterate over each bit in flags, and check the matching subsystem. */
   341     for (i = 0; i < num_subsystems; ++i) {
   342         if ((flags & 1) && SDL_SubsystemRefCount[i] > 0) {
   343             initialized |= (1 << i);
   344         }
   345 
   346         flags >>= 1;
   347     }
   348 
   349     return initialized;
   350 }
   351 
   352 void
   353 SDL_Quit(void)
   354 {
   355     SDL_bInMainQuit = SDL_TRUE;
   356 
   357     /* Quit all subsystems */
   358 #if SDL_VIDEO_DRIVER_WINDOWS
   359     SDL_HelperWindowDestroy();
   360 #endif
   361     SDL_QuitSubSystem(SDL_INIT_EVERYTHING);
   362 
   363     /* Uninstall any parachute signal handlers */
   364     SDL_UninstallParachute();
   365 
   366     SDL_ClearHints();
   367     SDL_AssertionsQuit();
   368     SDL_LogResetPriorities();
   369 
   370     /* Now that every subsystem has been quit, we reset the subsystem refcount
   371      * and the list of initialized subsystems.
   372      */
   373     SDL_memset( SDL_SubsystemRefCount, 0x0, sizeof(SDL_SubsystemRefCount) );
   374 
   375     SDL_bInMainQuit = SDL_FALSE;
   376 }
   377 
   378 /* Get the library version number */
   379 void
   380 SDL_GetVersion(SDL_version * ver)
   381 {
   382     SDL_VERSION(ver);
   383 }
   384 
   385 /* Get the library source revision */
   386 const char *
   387 SDL_GetRevision(void)
   388 {
   389     return SDL_REVISION;
   390 }
   391 
   392 /* Get the library source revision number */
   393 int
   394 SDL_GetRevisionNumber(void)
   395 {
   396     return SDL_REVISION_NUMBER;
   397 }
   398 
   399 /* Get the name of the platform */
   400 const char *
   401 SDL_GetPlatform()
   402 {
   403 #if __AIX__
   404     return "AIX";
   405 #elif __ANDROID__
   406     return "Android";
   407 #elif __BEOS__
   408     return "BeOS";
   409 #elif __BSDI__
   410     return "BSDI";
   411 #elif __DREAMCAST__
   412     return "Dreamcast";
   413 #elif __FREEBSD__
   414     return "FreeBSD";
   415 #elif __HAIKU__
   416     return "Haiku";
   417 #elif __HPUX__
   418     return "HP-UX";
   419 #elif __IRIX__
   420     return "Irix";
   421 #elif __LINUX__
   422     return "Linux";
   423 #elif __MINT__
   424     return "Atari MiNT";
   425 #elif __MACOS__
   426     return "MacOS Classic";
   427 #elif __MACOSX__
   428     return "Mac OS X";
   429 #elif __NETBSD__
   430     return "NetBSD";
   431 #elif __OPENBSD__
   432     return "OpenBSD";
   433 #elif __OS2__
   434     return "OS/2";
   435 #elif __OSF__
   436     return "OSF/1";
   437 #elif __QNXNTO__
   438     return "QNX Neutrino";
   439 #elif __RISCOS__
   440     return "RISC OS";
   441 #elif __SOLARIS__
   442     return "Solaris";
   443 #elif __WIN32__
   444     return "Windows";
   445 #elif __IPHONEOS__
   446     return "iPhone OS";
   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 #include "core/windows/SDL_windows.h"
   459 
   460 BOOL APIENTRY
   461 _DllMainCRTStartup(HANDLE hModule,
   462                    DWORD ul_reason_for_call, LPVOID lpReserved)
   463 {
   464     switch (ul_reason_for_call) {
   465     case DLL_PROCESS_ATTACH:
   466     case DLL_THREAD_ATTACH:
   467     case DLL_THREAD_DETACH:
   468     case DLL_PROCESS_DETACH:
   469         break;
   470     }
   471     return TRUE;
   472 }
   473 #endif /* building DLL with Watcom C */
   474 
   475 #endif /* __WIN32__ */
   476 
   477 /* vi: set sts=4 ts=4 sw=4 expandtab: */