src/SDL.c
changeset 6690 9548c8a58103
parent 6441 ada3545fed23
child 6866 e74a4b282450
     1.1 --- a/src/SDL.c	Mon Nov 26 14:59:07 2012 -0800
     1.2 +++ b/src/SDL.c	Mon Nov 26 16:37:54 2012 -0800
     1.3 @@ -44,7 +44,20 @@
     1.4  /* The initialized subsystems */
     1.5  static Uint32 SDL_initialized = 0;
     1.6  static Uint32 ticks_started = 0;
     1.7 +static SDL_bool SDL_bInMainQuit = SDL_FALSE;
     1.8 +static Uint8 SDL_SubsystemRefCount[ 32 ]; // keep a per subsystem init
     1.9  
    1.10 +/* helper func to return the index of the MSB in an int */
    1.11 +int msb32_idx( Uint32 n)
    1.12 +{
    1.13 +	int b = 0;
    1.14 +	if (!n) return -1;
    1.15 +
    1.16 +#define step(x) if (n >= ((Uint32)1) << x) b += x, n >>= x
    1.17 +	step(16); step(8); step(4); step(2); step(1);
    1.18 +#undef step
    1.19 +	return b;
    1.20 +}
    1.21  
    1.22  int
    1.23  SDL_InitSubSystem(Uint32 flags)
    1.24 @@ -55,11 +68,16 @@
    1.25          SDL_StartTicks();
    1.26          ticks_started = 1;
    1.27      }
    1.28 -    if ((flags & SDL_INIT_TIMER) && !(SDL_initialized & SDL_INIT_TIMER)) {
    1.29 -        if (SDL_TimerInit() < 0) {
    1.30 -            return (-1);
    1.31 -        }
    1.32 -        SDL_initialized |= SDL_INIT_TIMER;
    1.33 +
    1.34 +    if ((flags & SDL_INIT_TIMER) ){
    1.35 +		SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_TIMER) ]++;
    1.36 +		SDL_assert( SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_TIMER) ] < 254 );
    1.37 +		if ( !(SDL_initialized & SDL_INIT_TIMER)) {
    1.38 +			if (SDL_TimerInit() < 0) {
    1.39 +				return (-1);
    1.40 +			}
    1.41 +			SDL_initialized |= SDL_INIT_TIMER;
    1.42 +		}
    1.43      }
    1.44  #else
    1.45      if (flags & SDL_INIT_TIMER) {
    1.46 @@ -70,11 +88,15 @@
    1.47  
    1.48  #if !SDL_VIDEO_DISABLED
    1.49      /* Initialize the video/event subsystem */
    1.50 -    if ((flags & SDL_INIT_VIDEO) && !(SDL_initialized & SDL_INIT_VIDEO)) {
    1.51 -        if (SDL_VideoInit(NULL) < 0) {
    1.52 -            return (-1);
    1.53 -        }
    1.54 -        SDL_initialized |= SDL_INIT_VIDEO;
    1.55 +    if ((flags & SDL_INIT_VIDEO) ) {
    1.56 +		SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_VIDEO) ]++;
    1.57 +		SDL_assert( SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_VIDEO) ] < 254 );
    1.58 +		if ( !(SDL_initialized & SDL_INIT_VIDEO)) {
    1.59 +			if (SDL_VideoInit(NULL) < 0) {
    1.60 +				return (-1);
    1.61 +			}
    1.62 +			SDL_initialized |= SDL_INIT_VIDEO;
    1.63 +		}
    1.64      }
    1.65  #else
    1.66      if (flags & SDL_INIT_VIDEO) {
    1.67 @@ -85,11 +107,15 @@
    1.68  
    1.69  #if !SDL_AUDIO_DISABLED
    1.70      /* Initialize the audio subsystem */
    1.71 -    if ((flags & SDL_INIT_AUDIO) && !(SDL_initialized & SDL_INIT_AUDIO)) {
    1.72 -        if (SDL_AudioInit(NULL) < 0) {
    1.73 -            return (-1);
    1.74 -        }
    1.75 -        SDL_initialized |= SDL_INIT_AUDIO;
    1.76 +    if ((flags & SDL_INIT_AUDIO) ) {
    1.77 +		SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_AUDIO) ]++;
    1.78 +		SDL_assert( SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_AUDIO) ] < 254 );
    1.79 +		if ( !(SDL_initialized & SDL_INIT_AUDIO)) {
    1.80 +			if (SDL_AudioInit(NULL) < 0) {
    1.81 +				return (-1);
    1.82 +			}
    1.83 +			SDL_initialized |= SDL_INIT_AUDIO;
    1.84 +		}
    1.85      }
    1.86  #else
    1.87      if (flags & SDL_INIT_AUDIO) {
    1.88 @@ -100,10 +126,23 @@
    1.89  
    1.90  #if !SDL_JOYSTICK_DISABLED
    1.91      /* Initialize the joystick subsystem */
    1.92 -    if ((flags & SDL_INIT_JOYSTICK) && !(SDL_initialized & SDL_INIT_JOYSTICK)) {
    1.93 -        if (SDL_JoystickInit() < 0) {
    1.94 +    if ( ( (flags & SDL_INIT_JOYSTICK)  ) || ((flags & SDL_INIT_GAMECONTROLLER) ) ) { // game controller implies joystick
    1.95 +		SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_JOYSTICK) ]++;
    1.96 +		SDL_assert( SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_JOYSTICK) ] < 254 );
    1.97 +        if ( !(SDL_initialized & SDL_INIT_JOYSTICK) && SDL_JoystickInit() < 0) {
    1.98              return (-1);
    1.99          }
   1.100 +
   1.101 +		if ((flags & SDL_INIT_GAMECONTROLLER) ) {
   1.102 +			SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_GAMECONTROLLER) ]++;
   1.103 +			SDL_assert( SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_GAMECONTROLLER) ] < 254 );
   1.104 +			if ( !(SDL_initialized & SDL_INIT_GAMECONTROLLER)) {
   1.105 +				if (SDL_GameControllerInit() < 0) {
   1.106 +					return (-1);
   1.107 +				}
   1.108 +				SDL_initialized |= SDL_INIT_GAMECONTROLLER;
   1.109 +			}
   1.110 +		}
   1.111          SDL_initialized |= SDL_INIT_JOYSTICK;
   1.112      }
   1.113  #else
   1.114 @@ -115,11 +154,15 @@
   1.115  
   1.116  #if !SDL_HAPTIC_DISABLED
   1.117      /* Initialize the haptic subsystem */
   1.118 -    if ((flags & SDL_INIT_HAPTIC) && !(SDL_initialized & SDL_INIT_HAPTIC)) {
   1.119 -        if (SDL_HapticInit() < 0) {
   1.120 -            return (-1);
   1.121 -        }
   1.122 -        SDL_initialized |= SDL_INIT_HAPTIC;
   1.123 +    if ((flags & SDL_INIT_HAPTIC) ) {
   1.124 +		SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_HAPTIC) ]++;
   1.125 +		SDL_assert( SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_HAPTIC) ] < 254 );
   1.126 +		if ( !(SDL_initialized & SDL_INIT_HAPTIC)) {
   1.127 +			if (SDL_HapticInit() < 0) {
   1.128 +				return (-1);
   1.129 +			}
   1.130 +			SDL_initialized |= SDL_INIT_HAPTIC;
   1.131 +		}
   1.132      }
   1.133  #else
   1.134      if (flags & SDL_INIT_HAPTIC) {
   1.135 @@ -156,6 +199,7 @@
   1.136          SDL_InstallParachute();
   1.137      }
   1.138  
   1.139 +	SDL_memset( SDL_SubsystemRefCount, 0x0, sizeof(SDL_SubsystemRefCount) );
   1.140      return (0);
   1.141  }
   1.142  
   1.143 @@ -164,33 +208,62 @@
   1.144  {
   1.145      /* Shut down requested initialized subsystems */
   1.146  #if !SDL_JOYSTICK_DISABLED
   1.147 -    if ((flags & SDL_initialized & SDL_INIT_JOYSTICK)) {
   1.148 -        SDL_JoystickQuit();
   1.149 -        SDL_initialized &= ~SDL_INIT_JOYSTICK;
   1.150 +    if ((flags & SDL_initialized & SDL_INIT_JOYSTICK) || (flags & SDL_initialized & SDL_INIT_GAMECONTROLLER)) {
   1.151 +		if ( (flags & SDL_initialized & SDL_INIT_GAMECONTROLLER) ) {
   1.152 +			SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_GAMECONTROLLER) ]--;
   1.153 +			if ( SDL_bInMainQuit || SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_GAMECONTROLLER) ] == 0 ) {
   1.154 +				SDL_GameControllerQuit();
   1.155 +				SDL_initialized &= ~SDL_INIT_GAMECONTROLLER;
   1.156 +			}
   1.157 +		}
   1.158 +
   1.159 +		SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_JOYSTICK) ]--;
   1.160 +		if ( SDL_bInMainQuit || SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_JOYSTICK) ] == 0 )
   1.161 +		{
   1.162 +			SDL_JoystickQuit();
   1.163 +			SDL_initialized &= ~SDL_INIT_JOYSTICK;
   1.164 +		}
   1.165 +
   1.166      }
   1.167  #endif
   1.168  #if !SDL_HAPTIC_DISABLED
   1.169      if ((flags & SDL_initialized & SDL_INIT_HAPTIC)) {
   1.170 -        SDL_HapticQuit();
   1.171 -        SDL_initialized &= ~SDL_INIT_HAPTIC;
   1.172 +		SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_HAPTIC) ]--;
   1.173 +		if ( SDL_bInMainQuit || SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_HAPTIC) ] == 0 )
   1.174 +		{
   1.175 +			SDL_HapticQuit();
   1.176 +			SDL_initialized &= ~SDL_INIT_HAPTIC;
   1.177 +		}
   1.178      }
   1.179  #endif
   1.180  #if !SDL_AUDIO_DISABLED
   1.181      if ((flags & SDL_initialized & SDL_INIT_AUDIO)) {
   1.182 -        SDL_AudioQuit();
   1.183 -        SDL_initialized &= ~SDL_INIT_AUDIO;
   1.184 +		SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_AUDIO) ]--;
   1.185 +		if ( SDL_bInMainQuit || SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_AUDIO) ] == 0 )
   1.186 +		{
   1.187 +			SDL_AudioQuit();
   1.188 +			SDL_initialized &= ~SDL_INIT_AUDIO;
   1.189 +		}
   1.190      }
   1.191  #endif
   1.192  #if !SDL_VIDEO_DISABLED
   1.193      if ((flags & SDL_initialized & SDL_INIT_VIDEO)) {
   1.194 -        SDL_VideoQuit();
   1.195 -        SDL_initialized &= ~SDL_INIT_VIDEO;
   1.196 +		SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_VIDEO) ]--;
   1.197 +		if ( SDL_bInMainQuit || SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_VIDEO) ] == 0 )
   1.198 +		{
   1.199 +			SDL_VideoQuit();
   1.200 +			SDL_initialized &= ~SDL_INIT_VIDEO;
   1.201 +		}
   1.202      }
   1.203  #endif
   1.204  #if !SDL_TIMERS_DISABLED
   1.205      if ((flags & SDL_initialized & SDL_INIT_TIMER)) {
   1.206 -        SDL_TimerQuit();
   1.207 -        SDL_initialized &= ~SDL_INIT_TIMER;
   1.208 +		SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_TIMER) ]--;
   1.209 +		if ( SDL_bInMainQuit || SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_TIMER) ] == 0 )
   1.210 +		{
   1.211 +			SDL_TimerQuit();
   1.212 +			SDL_initialized &= ~SDL_INIT_TIMER;
   1.213 +		}
   1.214      }
   1.215  #endif
   1.216  }
   1.217 @@ -207,6 +280,7 @@
   1.218  void
   1.219  SDL_Quit(void)
   1.220  {
   1.221 +	SDL_bInMainQuit = SDL_TRUE;
   1.222      /* Quit all subsystems */
   1.223  #if defined(__WIN32__)
   1.224      SDL_HelperWindowDestroy();
   1.225 @@ -219,6 +293,9 @@
   1.226      SDL_ClearHints();
   1.227      SDL_AssertionsQuit();
   1.228      SDL_LogResetPriorities();
   1.229 +
   1.230 +	SDL_memset( SDL_SubsystemRefCount, 0x0, sizeof(SDL_SubsystemRefCount) );
   1.231 +	SDL_bInMainQuit = SDL_FALSE;
   1.232  }
   1.233  
   1.234  /* Get the library version number */