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