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