Don't clobber refcounting in SDL_Init.
- Fixes bug 1712 by not overwriting SDL_SubsystemRefCount in SDL_Init. - Removes the SDL_initialized variable, and makes SDL_SubsystemRefCount the canonical source of truth for whether or not a subsystem has been initialized. - Refactors SDL_InitSubSystem and SDL_QuitSubSystem to use helper functions to manage refcount. - Adds automated tests for SDL_Init/Quit*. - Adds SDL_bits.h which contains SDL_MostSignificantBitIndex.
This commit is contained in:
parent
781ab3764f
commit
f85aeb98c7
9 changed files with 411 additions and 140 deletions
|
@ -47,6 +47,7 @@ HDRS = \
|
||||||
SDL_assert.h \
|
SDL_assert.h \
|
||||||
SDL_atomic.h \
|
SDL_atomic.h \
|
||||||
SDL_audio.h \
|
SDL_audio.h \
|
||||||
|
SDL_bits.h \
|
||||||
SDL_blendmode.h \
|
SDL_blendmode.h \
|
||||||
SDL_clipboard.h \
|
SDL_clipboard.h \
|
||||||
SDL_cpuinfo.h \
|
SDL_cpuinfo.h \
|
||||||
|
|
|
@ -375,6 +375,10 @@
|
||||||
RelativePath="..\..\include\SDL_audio.h"
|
RelativePath="..\..\include\SDL_audio.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\include\SDL_bits.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\include\SDL_blendmode.h"
|
RelativePath="..\..\include\SDL_blendmode.h"
|
||||||
>
|
>
|
||||||
|
|
|
@ -207,6 +207,7 @@
|
||||||
<ClInclude Include="..\..\include\SDL_assert.h" />
|
<ClInclude Include="..\..\include\SDL_assert.h" />
|
||||||
<ClInclude Include="..\..\include\SDL_atomic.h" />
|
<ClInclude Include="..\..\include\SDL_atomic.h" />
|
||||||
<ClInclude Include="..\..\include\SDL_audio.h" />
|
<ClInclude Include="..\..\include\SDL_audio.h" />
|
||||||
|
<ClInclude Include="..\..\include\SDL_bits.h" />
|
||||||
<ClInclude Include="..\..\include\SDL_blendmode.h" />
|
<ClInclude Include="..\..\include\SDL_blendmode.h" />
|
||||||
<ClInclude Include="..\..\include\SDL_clipboard.h" />
|
<ClInclude Include="..\..\include\SDL_clipboard.h" />
|
||||||
<ClInclude Include="..\..\include\SDL_config.h" />
|
<ClInclude Include="..\..\include\SDL_config.h" />
|
||||||
|
|
|
@ -211,6 +211,7 @@
|
||||||
<ClInclude Include="..\..\include\SDL_assert.h" />
|
<ClInclude Include="..\..\include\SDL_assert.h" />
|
||||||
<ClInclude Include="..\..\include\SDL_atomic.h" />
|
<ClInclude Include="..\..\include\SDL_atomic.h" />
|
||||||
<ClInclude Include="..\..\include\SDL_audio.h" />
|
<ClInclude Include="..\..\include\SDL_audio.h" />
|
||||||
|
<ClInclude Include="..\..\include\SDL_bits.h" />
|
||||||
<ClInclude Include="..\..\include\SDL_blendmode.h" />
|
<ClInclude Include="..\..\include\SDL_blendmode.h" />
|
||||||
<ClInclude Include="..\..\include\SDL_clipboard.h" />
|
<ClInclude Include="..\..\include\SDL_clipboard.h" />
|
||||||
<ClInclude Include="..\..\include\SDL_config.h" />
|
<ClInclude Include="..\..\include\SDL_config.h" />
|
||||||
|
|
102
include/SDL_bits.h
Normal file
102
include/SDL_bits.h
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
/*
|
||||||
|
Simple DirectMedia Layer
|
||||||
|
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||||
|
|
||||||
|
This software is provided 'as-is', without any express or implied
|
||||||
|
warranty. In no event will the authors be held liable for any damages
|
||||||
|
arising from the use of this software.
|
||||||
|
|
||||||
|
Permission is granted to anyone to use this software for any purpose,
|
||||||
|
including commercial applications, and to alter it and redistribute it
|
||||||
|
freely, subject to the following restrictions:
|
||||||
|
|
||||||
|
1. The origin of this software must not be misrepresented; you must not
|
||||||
|
claim that you wrote the original software. If you use this software
|
||||||
|
in a product, an acknowledgment in the product documentation would be
|
||||||
|
appreciated but is not required.
|
||||||
|
2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
misrepresented as being the original software.
|
||||||
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \file SDL_bits.h
|
||||||
|
*
|
||||||
|
* Functions for fiddling with bits and bitmasks.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _SDL_bits_h
|
||||||
|
#define _SDL_bits_h
|
||||||
|
|
||||||
|
#include "SDL_stdinc.h"
|
||||||
|
|
||||||
|
#include "begin_code.h"
|
||||||
|
/* Set up for C function definitions, even when using C++ */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
extern "C" {
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \file SDL_bits.h
|
||||||
|
*
|
||||||
|
* Uses inline functions for compilers that support them, and static
|
||||||
|
* functions for those that do not. Because these functions become
|
||||||
|
* static for compilers that do not support inline functions, this
|
||||||
|
* header should only be included in files that actually use them.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the index of the most significant bit. Result is undefined when called
|
||||||
|
* with 0. This operation can also be stated as "count leading zeroes" and
|
||||||
|
* "log base 2".
|
||||||
|
*
|
||||||
|
* \return Index of the most significant bit.
|
||||||
|
*/
|
||||||
|
static __inline__ Sint8
|
||||||
|
SDL_MostSignificantBitIndex32(Uint32 x)
|
||||||
|
{
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
/* Count Leading Zeroes builtin in GCC.
|
||||||
|
* http://gcc.gnu.org/onlinedocs/gcc-4.3.4/gcc/Other-Builtins.html
|
||||||
|
*/
|
||||||
|
return 31 - __builtin_clz(x);
|
||||||
|
#else
|
||||||
|
/* Based off of Bit Twiddling Hacks by Sean Eron Anderson
|
||||||
|
* <seander@cs.stanford.edu>, released in the public domain.
|
||||||
|
* http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogLookup
|
||||||
|
*/
|
||||||
|
static const Sint8 LogTable256[256] =
|
||||||
|
{
|
||||||
|
#define LT(n) n, n, n, n, n, n, n, n, n, n, n, n, n, n, n, n
|
||||||
|
-1, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||||
|
LT(4), LT(5), LT(5), LT(6), LT(6), LT(6), LT(6),
|
||||||
|
LT(7), LT(7), LT(7), LT(7), LT(7), LT(7), LT(7), LT(7)
|
||||||
|
#undef LT
|
||||||
|
};
|
||||||
|
|
||||||
|
register unsigned int t, tt;
|
||||||
|
|
||||||
|
if (tt = x >> 16)
|
||||||
|
{
|
||||||
|
return ((t = tt >> 8) ? 24 + LogTable256[t] : 16 + LogTable256[tt]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return ((t = x >> 8) ? 8 + LogTable256[t] : LogTable256[x]);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ends C function definitions when using C++ */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
}
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
#endif
|
||||||
|
#include "close_code.h"
|
||||||
|
|
||||||
|
#endif /* _SDL_bits_h */
|
||||||
|
|
||||||
|
/* vi: set ts=4 sw=4 expandtab: */
|
306
src/SDL.c
306
src/SDL.c
|
@ -23,6 +23,7 @@
|
||||||
/* Initialization code for SDL */
|
/* Initialization code for SDL */
|
||||||
|
|
||||||
#include "SDL.h"
|
#include "SDL.h"
|
||||||
|
#include "SDL_bits.h"
|
||||||
#include "SDL_revision.h"
|
#include "SDL_revision.h"
|
||||||
#include "SDL_fatal.h"
|
#include "SDL_fatal.h"
|
||||||
#include "SDL_assert_c.h"
|
#include "SDL_assert_c.h"
|
||||||
|
@ -42,134 +43,146 @@ extern int SDL_HelperWindowDestroy(void);
|
||||||
|
|
||||||
|
|
||||||
/* The initialized subsystems */
|
/* The initialized subsystems */
|
||||||
static Uint32 SDL_initialized = 0;
|
|
||||||
static Uint32 ticks_started = 0;
|
static Uint32 ticks_started = 0;
|
||||||
static SDL_bool SDL_bInMainQuit = SDL_FALSE;
|
static SDL_bool SDL_bInMainQuit = SDL_FALSE;
|
||||||
static Uint8 SDL_SubsystemRefCount[ 32 ]; // keep a per subsystem init
|
static Uint8 SDL_SubsystemRefCount[ 32 ];
|
||||||
|
|
||||||
/* helper func to return the index of the MSB in an int */
|
/* Private helper to increment a subsystem's ref counter. */
|
||||||
int msb32_idx( Uint32 n)
|
static void SDL_PrivateSubsystemRefCountIncr(Uint32 subsystem)
|
||||||
{
|
{
|
||||||
int b = 0;
|
int subsystem_index = SDL_MostSignificantBitIndex32(subsystem);
|
||||||
if (!n) return -1;
|
SDL_assert(SDL_SubsystemRefCount[subsystem_index] < 255);
|
||||||
|
++SDL_SubsystemRefCount[subsystem_index];
|
||||||
|
}
|
||||||
|
|
||||||
#define step(x) if (n >= ((Uint32)1) << x) b += x, n >>= x
|
/* Private helper to decrement a subsystem's ref counter. */
|
||||||
step(16); step(8); step(4); step(2); step(1);
|
void SDL_PrivateSubsystemRefCountDecr(Uint32 subsystem)
|
||||||
#undef step
|
{
|
||||||
return b;
|
int subsystem_index = SDL_MostSignificantBitIndex32(subsystem);
|
||||||
|
if (SDL_SubsystemRefCount[subsystem_index] > 0) {
|
||||||
|
--SDL_SubsystemRefCount[subsystem_index];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Private helper to check if a system needs init. */
|
||||||
|
static SDL_bool
|
||||||
|
SDL_PrivateShouldInitSubsystem(Uint32 flags, Uint32 subsystem)
|
||||||
|
{
|
||||||
|
if ((flags & subsystem) == 0) {
|
||||||
|
return SDL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int subsystem_index = SDL_MostSignificantBitIndex32(subsystem);
|
||||||
|
SDL_assert(SDL_SubsystemRefCount[subsystem_index] < 255);
|
||||||
|
return (SDL_SubsystemRefCount[subsystem_index] == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Private helper to check if a system needs to be quit. */
|
||||||
|
static SDL_bool
|
||||||
|
SDL_PrivateShouldQuitSubsystem(Uint32 subsystem) {
|
||||||
|
int subsystem_index = SDL_MostSignificantBitIndex32(subsystem);
|
||||||
|
if (SDL_SubsystemRefCount[subsystem_index] == 0) {
|
||||||
|
return SDL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we're in SDL_Quit, we shut down every subsystem, even if refcount
|
||||||
|
* isn't zero.
|
||||||
|
*/
|
||||||
|
return SDL_SubsystemRefCount[subsystem_index] == 1 || SDL_bInMainQuit;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
SDL_InitSubSystem(Uint32 flags)
|
SDL_InitSubSystem(Uint32 flags)
|
||||||
{
|
{
|
||||||
#if !SDL_TIMERS_DISABLED
|
#if !SDL_TIMERS_DISABLED
|
||||||
/* Initialize the timer subsystem */
|
|
||||||
if (!ticks_started) {
|
if (!ticks_started) {
|
||||||
SDL_StartTicks();
|
SDL_StartTicks();
|
||||||
ticks_started = 1;
|
ticks_started = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((flags & SDL_INIT_TIMER) ){
|
|
||||||
SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_TIMER) ]++;
|
|
||||||
SDL_assert( SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_TIMER) ] < 254 );
|
|
||||||
if ( !(SDL_initialized & SDL_INIT_TIMER)) {
|
|
||||||
if (SDL_TimerInit() < 0) {
|
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
SDL_initialized |= SDL_INIT_TIMER;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if (flags & SDL_INIT_TIMER) {
|
|
||||||
SDL_SetError("SDL not built with timer support");
|
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !SDL_VIDEO_DISABLED
|
/* Initialize the timer subsystem */
|
||||||
/* Initialize the video/event subsystem */
|
if (SDL_PrivateShouldInitSubsystem(flags, SDL_INIT_TIMER)) {
|
||||||
if ((flags & SDL_INIT_VIDEO) ) {
|
#if !SDL_TIMERS_DISABLED
|
||||||
SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_VIDEO) ]++;
|
if (SDL_TimerInit() < 0) {
|
||||||
SDL_assert( SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_VIDEO) ] < 254 );
|
|
||||||
if ( !(SDL_initialized & SDL_INIT_VIDEO)) {
|
|
||||||
if (SDL_VideoInit(NULL) < 0) {
|
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
SDL_initialized |= SDL_INIT_VIDEO;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if (flags & SDL_INIT_VIDEO) {
|
|
||||||
SDL_SetError("SDL not built with video support");
|
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !SDL_AUDIO_DISABLED
|
|
||||||
/* Initialize the audio subsystem */
|
|
||||||
if ((flags & SDL_INIT_AUDIO) ) {
|
|
||||||
SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_AUDIO) ]++;
|
|
||||||
SDL_assert( SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_AUDIO) ] < 254 );
|
|
||||||
if ( !(SDL_initialized & SDL_INIT_AUDIO)) {
|
|
||||||
if (SDL_AudioInit(NULL) < 0) {
|
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
SDL_initialized |= SDL_INIT_AUDIO;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if (flags & SDL_INIT_AUDIO) {
|
|
||||||
SDL_SetError("SDL not built with audio support");
|
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !SDL_JOYSTICK_DISABLED
|
|
||||||
/* Initialize the joystick subsystem */
|
|
||||||
if ( ( (flags & SDL_INIT_JOYSTICK) ) || ((flags & SDL_INIT_GAMECONTROLLER) ) ) { // game controller implies joystick
|
|
||||||
SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_JOYSTICK) ]++;
|
|
||||||
SDL_assert( SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_JOYSTICK) ] < 254 );
|
|
||||||
if ( !(SDL_initialized & SDL_INIT_JOYSTICK) && SDL_JoystickInit() < 0) {
|
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
SDL_PrivateSubsystemRefCountIncr(SDL_INIT_TIMER);
|
||||||
if ((flags & SDL_INIT_GAMECONTROLLER) ) {
|
#else
|
||||||
SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_GAMECONTROLLER) ]++;
|
SDL_SetError("SDL not built with timer support");
|
||||||
SDL_assert( SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_GAMECONTROLLER) ] < 254 );
|
return (-1);
|
||||||
if ( !(SDL_initialized & SDL_INIT_GAMECONTROLLER)) {
|
#endif
|
||||||
if (SDL_GameControllerInit() < 0) {
|
}
|
||||||
return (-1);
|
|
||||||
}
|
/* Initialize the video/event subsystem */
|
||||||
SDL_initialized |= SDL_INIT_GAMECONTROLLER;
|
if (SDL_PrivateShouldInitSubsystem(flags, SDL_INIT_VIDEO)) {
|
||||||
}
|
#if !SDL_VIDEO_DISABLED
|
||||||
}
|
if (SDL_VideoInit(NULL) < 0) {
|
||||||
SDL_initialized |= SDL_INIT_JOYSTICK;
|
return (-1);
|
||||||
}
|
}
|
||||||
|
SDL_PrivateSubsystemRefCountIncr(SDL_INIT_VIDEO);
|
||||||
|
#else
|
||||||
|
SDL_SetError("SDL not built with video support");
|
||||||
|
return (-1);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize the audio subsystem */
|
||||||
|
if (SDL_PrivateShouldInitSubsystem(flags, SDL_INIT_AUDIO)) {
|
||||||
|
#if !SDL_AUDIO_DISABLED
|
||||||
|
if (SDL_AudioInit(NULL) < 0) {
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
SDL_PrivateSubsystemRefCountIncr(SDL_INIT_AUDIO);
|
||||||
|
#else
|
||||||
|
SDL_SetError("SDL not built with audio support");
|
||||||
|
return (-1);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((flags & SDL_INIT_GAMECONTROLLER)) {
|
||||||
|
// Game controller implies Joystick.
|
||||||
|
flags |= SDL_INIT_JOYSTICK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize the joystick subsystem */
|
||||||
|
if (SDL_PrivateShouldInitSubsystem(flags, SDL_INIT_JOYSTICK)) {
|
||||||
|
#if !SDL_JOYSTICK_DISABLED
|
||||||
|
if (SDL_JoystickInit() < 0) {
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
SDL_PrivateSubsystemRefCountIncr(SDL_INIT_JOYSTICK);
|
||||||
#else
|
#else
|
||||||
if (flags & SDL_INIT_JOYSTICK) {
|
|
||||||
SDL_SetError("SDL not built with joystick support");
|
SDL_SetError("SDL not built with joystick support");
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !SDL_HAPTIC_DISABLED
|
|
||||||
/* Initialize the haptic subsystem */
|
|
||||||
if ((flags & SDL_INIT_HAPTIC) ) {
|
|
||||||
SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_HAPTIC) ]++;
|
|
||||||
SDL_assert( SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_HAPTIC) ] < 254 );
|
|
||||||
if ( !(SDL_initialized & SDL_INIT_HAPTIC)) {
|
|
||||||
if (SDL_HapticInit() < 0) {
|
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
SDL_initialized |= SDL_INIT_HAPTIC;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (SDL_PrivateShouldInitSubsystem(flags, SDL_INIT_GAMECONTROLLER)) {
|
||||||
|
#if !SDL_JOYSTICK_DISABLED
|
||||||
|
if (SDL_GameControllerInit() < 0) {
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
SDL_PrivateSubsystemRefCountIncr(SDL_INIT_GAMECONTROLLER);
|
||||||
|
#else
|
||||||
|
SDL_SetError("SDL not built with joystick support");
|
||||||
|
return (-1);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize the haptic subsystem */
|
||||||
|
if (SDL_PrivateShouldInitSubsystem(flags, SDL_INIT_HAPTIC)) {
|
||||||
|
#if !SDL_HAPTIC_DISABLED
|
||||||
|
if (SDL_HapticInit() < 0) {
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
SDL_PrivateSubsystemRefCountIncr(SDL_INIT_HAPTIC);
|
||||||
#else
|
#else
|
||||||
if (flags & SDL_INIT_HAPTIC) {
|
|
||||||
SDL_SetError("SDL not built with haptic (force feedback) support");
|
SDL_SetError("SDL not built with haptic (force feedback) support");
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,7 +212,6 @@ SDL_Init(Uint32 flags)
|
||||||
SDL_InstallParachute();
|
SDL_InstallParachute();
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_memset( SDL_SubsystemRefCount, 0x0, sizeof(SDL_SubsystemRefCount) );
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,62 +220,57 @@ SDL_QuitSubSystem(Uint32 flags)
|
||||||
{
|
{
|
||||||
/* Shut down requested initialized subsystems */
|
/* Shut down requested initialized subsystems */
|
||||||
#if !SDL_JOYSTICK_DISABLED
|
#if !SDL_JOYSTICK_DISABLED
|
||||||
if ((flags & SDL_initialized & SDL_INIT_JOYSTICK) || (flags & SDL_initialized & SDL_INIT_GAMECONTROLLER)) {
|
if ((flags & SDL_INIT_GAMECONTROLLER)) {
|
||||||
if ( (flags & SDL_initialized & SDL_INIT_GAMECONTROLLER) ) {
|
// Game controller implies Joystick.
|
||||||
SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_GAMECONTROLLER) ]--;
|
flags |= SDL_INIT_JOYSTICK;
|
||||||
if ( SDL_bInMainQuit || SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_GAMECONTROLLER) ] == 0 ) {
|
|
||||||
SDL_GameControllerQuit();
|
|
||||||
SDL_initialized &= ~SDL_INIT_GAMECONTROLLER;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_JOYSTICK) ]--;
|
if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_GAMECONTROLLER)) {
|
||||||
if ( SDL_bInMainQuit || SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_JOYSTICK) ] == 0 )
|
SDL_GameControllerQuit();
|
||||||
{
|
}
|
||||||
|
SDL_PrivateSubsystemRefCountDecr(SDL_INIT_GAMECONTROLLER);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((flags & SDL_INIT_JOYSTICK)) {
|
||||||
|
if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_JOYSTICK)) {
|
||||||
SDL_JoystickQuit();
|
SDL_JoystickQuit();
|
||||||
SDL_initialized &= ~SDL_INIT_JOYSTICK;
|
|
||||||
}
|
}
|
||||||
|
SDL_PrivateSubsystemRefCountDecr(SDL_INIT_JOYSTICK);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#if !SDL_HAPTIC_DISABLED
|
#if !SDL_HAPTIC_DISABLED
|
||||||
if ((flags & SDL_initialized & SDL_INIT_HAPTIC)) {
|
if ((flags & SDL_INIT_HAPTIC)) {
|
||||||
SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_HAPTIC) ]--;
|
if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_HAPTIC)) {
|
||||||
if ( SDL_bInMainQuit || SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_HAPTIC) ] == 0 )
|
|
||||||
{
|
|
||||||
SDL_HapticQuit();
|
SDL_HapticQuit();
|
||||||
SDL_initialized &= ~SDL_INIT_HAPTIC;
|
|
||||||
}
|
}
|
||||||
|
SDL_PrivateSubsystemRefCountDecr(SDL_INIT_HAPTIC);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !SDL_AUDIO_DISABLED
|
#if !SDL_AUDIO_DISABLED
|
||||||
if ((flags & SDL_initialized & SDL_INIT_AUDIO)) {
|
if ((flags & SDL_INIT_AUDIO)) {
|
||||||
SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_AUDIO) ]--;
|
if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_AUDIO)) {
|
||||||
if ( SDL_bInMainQuit || SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_AUDIO) ] == 0 )
|
|
||||||
{
|
|
||||||
SDL_AudioQuit();
|
SDL_AudioQuit();
|
||||||
SDL_initialized &= ~SDL_INIT_AUDIO;
|
|
||||||
}
|
}
|
||||||
|
SDL_PrivateSubsystemRefCountDecr(SDL_INIT_AUDIO);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !SDL_VIDEO_DISABLED
|
#if !SDL_VIDEO_DISABLED
|
||||||
if ((flags & SDL_initialized & SDL_INIT_VIDEO)) {
|
if ((flags & SDL_INIT_VIDEO)) {
|
||||||
SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_VIDEO) ]--;
|
if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_VIDEO)) {
|
||||||
if ( SDL_bInMainQuit || SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_VIDEO) ] == 0 )
|
|
||||||
{
|
|
||||||
SDL_VideoQuit();
|
SDL_VideoQuit();
|
||||||
SDL_initialized &= ~SDL_INIT_VIDEO;
|
|
||||||
}
|
}
|
||||||
|
SDL_PrivateSubsystemRefCountDecr(SDL_INIT_VIDEO);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !SDL_TIMERS_DISABLED
|
#if !SDL_TIMERS_DISABLED
|
||||||
if ((flags & SDL_initialized & SDL_INIT_TIMER)) {
|
if ((flags & SDL_INIT_TIMER)) {
|
||||||
SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_TIMER) ]--;
|
if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_TIMER)) {
|
||||||
if ( SDL_bInMainQuit || SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_TIMER) ] == 0 )
|
|
||||||
{
|
|
||||||
SDL_TimerQuit();
|
SDL_TimerQuit();
|
||||||
SDL_initialized &= ~SDL_INIT_TIMER;
|
|
||||||
}
|
}
|
||||||
|
SDL_PrivateSubsystemRefCountDecr(SDL_INIT_TIMER);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -271,16 +278,33 @@ SDL_QuitSubSystem(Uint32 flags)
|
||||||
Uint32
|
Uint32
|
||||||
SDL_WasInit(Uint32 flags)
|
SDL_WasInit(Uint32 flags)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
int num_subsystems = SDL_arraysize(SDL_SubsystemRefCount);
|
||||||
|
Uint32 initialized = 0;
|
||||||
|
|
||||||
if (!flags) {
|
if (!flags) {
|
||||||
flags = SDL_INIT_EVERYTHING;
|
flags = SDL_INIT_EVERYTHING;
|
||||||
}
|
}
|
||||||
return (SDL_initialized & flags);
|
|
||||||
|
num_subsystems = SDL_min(num_subsystems, SDL_MostSignificantBitIndex32(flags) + 1);
|
||||||
|
|
||||||
|
/* Iterate over each bit in flags, and check the matching subsystem. */
|
||||||
|
for (i = 0; i < num_subsystems; ++i) {
|
||||||
|
if ((flags & 1) && SDL_SubsystemRefCount[i] > 0) {
|
||||||
|
initialized |= (1 << i);
|
||||||
|
}
|
||||||
|
|
||||||
|
flags >>= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return initialized;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SDL_Quit(void)
|
SDL_Quit(void)
|
||||||
{
|
{
|
||||||
SDL_bInMainQuit = SDL_TRUE;
|
SDL_bInMainQuit = SDL_TRUE;
|
||||||
|
|
||||||
/* Quit all subsystems */
|
/* Quit all subsystems */
|
||||||
#if defined(__WIN32__)
|
#if defined(__WIN32__)
|
||||||
SDL_HelperWindowDestroy();
|
SDL_HelperWindowDestroy();
|
||||||
|
@ -294,8 +318,12 @@ SDL_Quit(void)
|
||||||
SDL_AssertionsQuit();
|
SDL_AssertionsQuit();
|
||||||
SDL_LogResetPriorities();
|
SDL_LogResetPriorities();
|
||||||
|
|
||||||
SDL_memset( SDL_SubsystemRefCount, 0x0, sizeof(SDL_SubsystemRefCount) );
|
/* Now that every subsystem has been quit, we reset the subsystem refcount
|
||||||
SDL_bInMainQuit = SDL_FALSE;
|
* and the list of initialized subsystems.
|
||||||
|
*/
|
||||||
|
SDL_memset( SDL_SubsystemRefCount, 0x0, sizeof(SDL_SubsystemRefCount) );
|
||||||
|
|
||||||
|
SDL_bInMainQuit = SDL_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the library version number */
|
/* Get the library version number */
|
||||||
|
|
|
@ -70,6 +70,7 @@ testaudioinfo$(EXE): $(srcdir)/testaudioinfo.c
|
||||||
|
|
||||||
testautomation$(EXE): $(srcdir)/testautomation.c \
|
testautomation$(EXE): $(srcdir)/testautomation.c \
|
||||||
$(srcdir)/testautomation_clipboard.c \
|
$(srcdir)/testautomation_clipboard.c \
|
||||||
|
$(srcdir)/testautomation_main.c \
|
||||||
$(srcdir)/testautomation_platform.c \
|
$(srcdir)/testautomation_platform.c \
|
||||||
$(srcdir)/testautomation_rect.c \
|
$(srcdir)/testautomation_rect.c \
|
||||||
$(srcdir)/testautomation_render.c \
|
$(srcdir)/testautomation_render.c \
|
||||||
|
|
131
test/testautomation_main.c
Normal file
131
test/testautomation_main.c
Normal file
|
@ -0,0 +1,131 @@
|
||||||
|
/**
|
||||||
|
* Automated SDL subsystems management test.
|
||||||
|
*
|
||||||
|
* Written by Jørgen Tjernø "jorgenpt"
|
||||||
|
*
|
||||||
|
* Released under Public Domain.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "SDL.h"
|
||||||
|
#include "SDL_test.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Tests SDL_Init() and SDL_Quit()
|
||||||
|
* \sa
|
||||||
|
* http://wiki.libsdl.org/moin.cgi/SDL_Init
|
||||||
|
* http://wiki.libsdl.org/moin.cgi/SDL_Quit
|
||||||
|
*/
|
||||||
|
static int main_testInitQuit (void *arg)
|
||||||
|
{
|
||||||
|
int initialized_subsystems = SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC;
|
||||||
|
|
||||||
|
SDLTest_AssertCheck( SDL_Init(initialized_subsystems) == 0, "SDL_Init multiple systems." );
|
||||||
|
|
||||||
|
int enabled_subsystems = SDL_WasInit(initialized_subsystems);
|
||||||
|
SDLTest_AssertCheck( enabled_subsystems == initialized_subsystems, "SDL_WasInit(SDL_INIT_EVERYTHING) contains all systems (%i)", enabled_subsystems );
|
||||||
|
|
||||||
|
SDL_Quit();
|
||||||
|
|
||||||
|
enabled_subsystems = SDL_WasInit(initialized_subsystems);
|
||||||
|
SDLTest_AssertCheck( enabled_subsystems == 0, "SDL_Quit should shut down everything (%i)", enabled_subsystems );
|
||||||
|
|
||||||
|
return TEST_COMPLETED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Tests SDL_InitSubSystem() and SDL_QuitSubSystem()
|
||||||
|
* \sa
|
||||||
|
* http://wiki.libsdl.org/moin.cgi/SDL_Init
|
||||||
|
* http://wiki.libsdl.org/moin.cgi/SDL_Quit
|
||||||
|
*/
|
||||||
|
static int main_testInitQuitSubSystem (void *arg)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int subsystems[] = { SDL_INIT_JOYSTICK, SDL_INIT_HAPTIC, SDL_INIT_GAMECONTROLLER };
|
||||||
|
|
||||||
|
for (i = 0; i < SDL_arraysize(subsystems); ++i) {
|
||||||
|
int subsystem = subsystems[i];
|
||||||
|
|
||||||
|
SDLTest_AssertCheck( (SDL_WasInit(subsystem) & subsystem) == 0, "SDL_WasInit(%x) before init should be false", subsystem );
|
||||||
|
SDLTest_AssertCheck( SDL_InitSubSystem(subsystem) == 0, "SDL_InitSubSystem(%x)", subsystem );
|
||||||
|
|
||||||
|
int initialized_system = SDL_WasInit(subsystem);
|
||||||
|
SDLTest_AssertCheck( (initialized_system & subsystem) != 0, "SDL_WasInit(%x) should be true (%x)", subsystem, initialized_system );
|
||||||
|
|
||||||
|
SDL_QuitSubSystem(subsystem);
|
||||||
|
|
||||||
|
SDLTest_AssertCheck( (SDL_WasInit(subsystem) & subsystem) == 0, "SDL_WasInit(%x) after shutdown should be false", subsystem );
|
||||||
|
}
|
||||||
|
|
||||||
|
return TEST_COMPLETED;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int joy_and_controller = SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER;
|
||||||
|
static int main_testImpliedJoystickInit (void *arg)
|
||||||
|
{
|
||||||
|
// First initialize the controller
|
||||||
|
SDLTest_AssertCheck( (SDL_WasInit(joy_and_controller) & joy_and_controller) == 0, "SDL_WasInit() before init should be false for joystick & controller" );
|
||||||
|
SDLTest_AssertCheck( SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER) == 0, "SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER)" );
|
||||||
|
|
||||||
|
// Then make sure this implicitly initialized the joystick subsystem
|
||||||
|
int initialized_system = SDL_WasInit(joy_and_controller);
|
||||||
|
SDLTest_AssertCheck( (initialized_system & joy_and_controller) == joy_and_controller, "SDL_WasInit() should be true for joystick & controller (%x)", initialized_system );
|
||||||
|
|
||||||
|
// Then quit the controller, and make sure that imlicity also quits the
|
||||||
|
// joystick subsystem
|
||||||
|
SDL_QuitSubSystem(SDL_INIT_GAMECONTROLLER);
|
||||||
|
initialized_system = SDL_WasInit(joy_and_controller);
|
||||||
|
SDLTest_AssertCheck( (initialized_system & joy_and_controller) == 0, "SDL_WasInit() should be false for joystick & controller (%x)", initialized_system );
|
||||||
|
}
|
||||||
|
|
||||||
|
static int main_testImpliedJoystickQuit (void *arg)
|
||||||
|
{
|
||||||
|
// First initialize the controller and the joystick (explicitly)
|
||||||
|
SDLTest_AssertCheck( (SDL_WasInit(joy_and_controller) & joy_and_controller) == 0, "SDL_WasInit() before init should be false for joystick & controller" );
|
||||||
|
SDLTest_AssertCheck( SDL_InitSubSystem(SDL_INIT_JOYSTICK) == 0, "SDL_InitSubSystem(SDL_INIT_JOYSTICK)" );
|
||||||
|
SDLTest_AssertCheck( SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER) == 0, "SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER)" );
|
||||||
|
|
||||||
|
// Then make sure they're both initialized properly
|
||||||
|
int initialized_system = SDL_WasInit(joy_and_controller);
|
||||||
|
SDLTest_AssertCheck( (initialized_system & joy_and_controller) == joy_and_controller, "SDL_WasInit() should be true for joystick & controller (%x)", initialized_system );
|
||||||
|
|
||||||
|
// Then quit the controller, and make sure that it does NOT quit the
|
||||||
|
// explicitly initialized joystick subsystem.
|
||||||
|
SDL_QuitSubSystem(SDL_INIT_GAMECONTROLLER);
|
||||||
|
initialized_system = SDL_WasInit(joy_and_controller);
|
||||||
|
SDLTest_AssertCheck( (initialized_system & joy_and_controller) == SDL_INIT_JOYSTICK, "SDL_WasInit() should be false for joystick & controller (%x)", initialized_system );
|
||||||
|
|
||||||
|
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const SDLTest_TestCaseReference mainTest1 =
|
||||||
|
{ (SDLTest_TestCaseFp)main_testInitQuit, "main_testInitQuit", "Tests SDL_Init/Quit", TEST_ENABLED};
|
||||||
|
|
||||||
|
static const SDLTest_TestCaseReference mainTest2 =
|
||||||
|
{ (SDLTest_TestCaseFp)main_testInitQuitSubSystem, "main_testInitQuitSubSystem", "Tests SDL_InitSubSystem/QuitSubSystem", TEST_ENABLED};
|
||||||
|
|
||||||
|
static const SDLTest_TestCaseReference mainTest3 =
|
||||||
|
{ (SDLTest_TestCaseFp)main_testImpliedJoystickInit, "main_testImpliedJoystickInit", "Tests that init for gamecontroller properly implies joystick", TEST_ENABLED};
|
||||||
|
|
||||||
|
static const SDLTest_TestCaseReference mainTest4 =
|
||||||
|
{ (SDLTest_TestCaseFp)main_testImpliedJoystickQuit, "main_testImpliedJoystickQuit", "Tests that quit for gamecontroller doesn't quit joystick if you inited it explicitly", TEST_ENABLED};
|
||||||
|
|
||||||
|
/* Sequence of Platform test cases */
|
||||||
|
static const SDLTest_TestCaseReference *mainTests[] = {
|
||||||
|
&mainTest1,
|
||||||
|
&mainTest2,
|
||||||
|
&mainTest3,
|
||||||
|
&mainTest4,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Platform test suite (global) */
|
||||||
|
SDLTest_TestSuiteReference mainTestSuite = {
|
||||||
|
"Main",
|
||||||
|
NULL,
|
||||||
|
mainTests,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
/* vi: set ts=4 sw=4 expandtab: */
|
|
@ -13,6 +13,7 @@ extern SDLTest_TestSuiteReference audioTestSuite;
|
||||||
extern SDLTest_TestSuiteReference clipboardTestSuite;
|
extern SDLTest_TestSuiteReference clipboardTestSuite;
|
||||||
extern SDLTest_TestSuiteReference eventsTestSuite;
|
extern SDLTest_TestSuiteReference eventsTestSuite;
|
||||||
extern SDLTest_TestSuiteReference keyboardTestSuite;
|
extern SDLTest_TestSuiteReference keyboardTestSuite;
|
||||||
|
extern SDLTest_TestSuiteReference mainTestSuite;
|
||||||
extern SDLTest_TestSuiteReference platformTestSuite;
|
extern SDLTest_TestSuiteReference platformTestSuite;
|
||||||
extern SDLTest_TestSuiteReference rectTestSuite;
|
extern SDLTest_TestSuiteReference rectTestSuite;
|
||||||
extern SDLTest_TestSuiteReference renderTestSuite;
|
extern SDLTest_TestSuiteReference renderTestSuite;
|
||||||
|
@ -30,6 +31,7 @@ SDLTest_TestSuiteReference *testSuites[] = {
|
||||||
&clipboardTestSuite,
|
&clipboardTestSuite,
|
||||||
&eventsTestSuite,
|
&eventsTestSuite,
|
||||||
&keyboardTestSuite,
|
&keyboardTestSuite,
|
||||||
|
&mainTestSuite,
|
||||||
&platformTestSuite,
|
&platformTestSuite,
|
||||||
&rectTestSuite,
|
&rectTestSuite,
|
||||||
&renderTestSuite,
|
&renderTestSuite,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue