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