diff --git a/Makefile.in b/Makefile.in index 84fd91ac2..07bfca238 100644 --- a/Makefile.in +++ b/Makefile.in @@ -47,6 +47,7 @@ HDRS = \ SDL_assert.h \ SDL_atomic.h \ SDL_audio.h \ + SDL_bits.h \ SDL_blendmode.h \ SDL_clipboard.h \ SDL_cpuinfo.h \ diff --git a/VisualC/SDL/SDL_VS2008.vcproj b/VisualC/SDL/SDL_VS2008.vcproj index 802f7f36c..737f0cbc8 100644 --- a/VisualC/SDL/SDL_VS2008.vcproj +++ b/VisualC/SDL/SDL_VS2008.vcproj @@ -375,6 +375,10 @@ RelativePath="..\..\include\SDL_audio.h" > + + diff --git a/VisualC/SDL/SDL_VS2010.vcxproj b/VisualC/SDL/SDL_VS2010.vcxproj index 8b5d18883..4b1aa890e 100644 --- a/VisualC/SDL/SDL_VS2010.vcxproj +++ b/VisualC/SDL/SDL_VS2010.vcxproj @@ -207,6 +207,7 @@ + diff --git a/VisualC/SDL/SDL_VS2012.vcxproj b/VisualC/SDL/SDL_VS2012.vcxproj index 55852fe22..6016263cc 100644 --- a/VisualC/SDL/SDL_VS2012.vcxproj +++ b/VisualC/SDL/SDL_VS2012.vcxproj @@ -211,6 +211,7 @@ + @@ -454,4 +455,4 @@ - \ No newline at end of file + diff --git a/include/SDL_bits.h b/include/SDL_bits.h new file mode 100644 index 000000000..2b1118dbb --- /dev/null +++ b/include/SDL_bits.h @@ -0,0 +1,102 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2013 Sam Lantinga + + 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 + * , 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: */ diff --git a/src/SDL.c b/src/SDL.c index 0cf39ecc1..a87f6c34b 100644 --- a/src/SDL.c +++ b/src/SDL.c @@ -23,6 +23,7 @@ /* Initialization code for SDL */ #include "SDL.h" +#include "SDL_bits.h" #include "SDL_revision.h" #include "SDL_fatal.h" #include "SDL_assert_c.h" @@ -42,134 +43,146 @@ extern int SDL_HelperWindowDestroy(void); /* The initialized subsystems */ -static Uint32 SDL_initialized = 0; static Uint32 ticks_started = 0; 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 */ -int msb32_idx( Uint32 n) +/* Private helper to increment a subsystem's ref counter. */ +static void SDL_PrivateSubsystemRefCountIncr(Uint32 subsystem) { - int b = 0; - if (!n) return -1; + int subsystem_index = SDL_MostSignificantBitIndex32(subsystem); + SDL_assert(SDL_SubsystemRefCount[subsystem_index] < 255); + ++SDL_SubsystemRefCount[subsystem_index]; +} + +/* Private helper to decrement a subsystem's ref counter. */ +void SDL_PrivateSubsystemRefCountDecr(Uint32 subsystem) +{ + 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); +} -#define step(x) if (n >= ((Uint32)1) << x) b += x, n >>= x - step(16); step(8); step(4); step(2); step(1); -#undef step - return b; +/* 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 SDL_InitSubSystem(Uint32 flags) { #if !SDL_TIMERS_DISABLED - /* Initialize the timer subsystem */ if (!ticks_started) { SDL_StartTicks(); ticks_started = 1; } +#endif - 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; - } - } + /* Initialize the timer subsystem */ + if (SDL_PrivateShouldInitSubsystem(flags, SDL_INIT_TIMER)) { +#if !SDL_TIMERS_DISABLED + if (SDL_TimerInit() < 0) { + return (-1); + } + SDL_PrivateSubsystemRefCountIncr(SDL_INIT_TIMER); #else - if (flags & SDL_INIT_TIMER) { SDL_SetError("SDL not built with timer support"); return (-1); - } #endif + } -#if !SDL_VIDEO_DISABLED /* Initialize the video/event subsystem */ - if ((flags & SDL_INIT_VIDEO) ) { - SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_VIDEO) ]++; - 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; - } - } + if (SDL_PrivateShouldInitSubsystem(flags, SDL_INIT_VIDEO)) { +#if !SDL_VIDEO_DISABLED + if (SDL_VideoInit(NULL) < 0) { + return (-1); + } + SDL_PrivateSubsystemRefCountIncr(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; - } - } + if (SDL_PrivateShouldInitSubsystem(flags, SDL_INIT_AUDIO)) { +#if !SDL_AUDIO_DISABLED + if (SDL_AudioInit(NULL) < 0) { + return (-1); + } + SDL_PrivateSubsystemRefCountIncr(SDL_INIT_AUDIO); #else - if (flags & SDL_INIT_AUDIO) { SDL_SetError("SDL not built with audio support"); return (-1); - } #endif + } + + if ((flags & SDL_INIT_GAMECONTROLLER)) { + // Game controller implies Joystick. + flags |= SDL_INIT_JOYSTICK; + } -#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) { + if (SDL_PrivateShouldInitSubsystem(flags, SDL_INIT_JOYSTICK)) { +#if !SDL_JOYSTICK_DISABLED + if (SDL_JoystickInit() < 0) { return (-1); } - - if ((flags & SDL_INIT_GAMECONTROLLER) ) { - SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_GAMECONTROLLER) ]++; - SDL_assert( SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_GAMECONTROLLER) ] < 254 ); - if ( !(SDL_initialized & SDL_INIT_GAMECONTROLLER)) { - if (SDL_GameControllerInit() < 0) { - return (-1); - } - SDL_initialized |= SDL_INIT_GAMECONTROLLER; - } - } - SDL_initialized |= SDL_INIT_JOYSTICK; - } + SDL_PrivateSubsystemRefCountIncr(SDL_INIT_JOYSTICK); #else - if (flags & SDL_INIT_JOYSTICK) { SDL_SetError("SDL not built with joystick support"); return (-1); +#endif } + + 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 + } -#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_HAPTIC)) { +#if !SDL_HAPTIC_DISABLED + if (SDL_HapticInit() < 0) { + return (-1); + } + SDL_PrivateSubsystemRefCountIncr(SDL_INIT_HAPTIC); #else - if (flags & SDL_INIT_HAPTIC) { SDL_SetError("SDL not built with haptic (force feedback) support"); return (-1); - } #endif + } + return (0); } @@ -199,7 +212,6 @@ SDL_Init(Uint32 flags) SDL_InstallParachute(); } - SDL_memset( SDL_SubsystemRefCount, 0x0, sizeof(SDL_SubsystemRefCount) ); return (0); } @@ -208,62 +220,57 @@ SDL_QuitSubSystem(Uint32 flags) { /* Shut down requested initialized subsystems */ #if !SDL_JOYSTICK_DISABLED - if ((flags & SDL_initialized & SDL_INIT_JOYSTICK) || (flags & SDL_initialized & SDL_INIT_GAMECONTROLLER)) { - if ( (flags & SDL_initialized & SDL_INIT_GAMECONTROLLER) ) { - SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_GAMECONTROLLER) ]--; - if ( SDL_bInMainQuit || SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_GAMECONTROLLER) ] == 0 ) { - SDL_GameControllerQuit(); - SDL_initialized &= ~SDL_INIT_GAMECONTROLLER; - } + if ((flags & SDL_INIT_GAMECONTROLLER)) { + // Game controller implies Joystick. + flags |= SDL_INIT_JOYSTICK; + + if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_GAMECONTROLLER)) { + SDL_GameControllerQuit(); } + SDL_PrivateSubsystemRefCountDecr(SDL_INIT_GAMECONTROLLER); + } - SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_JOYSTICK) ]--; - if ( SDL_bInMainQuit || SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_JOYSTICK) ] == 0 ) - { + if ((flags & SDL_INIT_JOYSTICK)) { + if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_JOYSTICK)) { SDL_JoystickQuit(); - SDL_initialized &= ~SDL_INIT_JOYSTICK; } - + SDL_PrivateSubsystemRefCountDecr(SDL_INIT_JOYSTICK); } #endif + #if !SDL_HAPTIC_DISABLED - if ((flags & SDL_initialized & SDL_INIT_HAPTIC)) { - SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_HAPTIC) ]--; - if ( SDL_bInMainQuit || SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_HAPTIC) ] == 0 ) - { + if ((flags & SDL_INIT_HAPTIC)) { + if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_HAPTIC)) { SDL_HapticQuit(); - SDL_initialized &= ~SDL_INIT_HAPTIC; } + SDL_PrivateSubsystemRefCountDecr(SDL_INIT_HAPTIC); } #endif + #if !SDL_AUDIO_DISABLED - if ((flags & SDL_initialized & SDL_INIT_AUDIO)) { - SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_AUDIO) ]--; - if ( SDL_bInMainQuit || SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_AUDIO) ] == 0 ) - { + if ((flags & SDL_INIT_AUDIO)) { + if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_AUDIO)) { SDL_AudioQuit(); - SDL_initialized &= ~SDL_INIT_AUDIO; } + SDL_PrivateSubsystemRefCountDecr(SDL_INIT_AUDIO); } #endif + #if !SDL_VIDEO_DISABLED - if ((flags & SDL_initialized & SDL_INIT_VIDEO)) { - SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_VIDEO) ]--; - if ( SDL_bInMainQuit || SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_VIDEO) ] == 0 ) - { + if ((flags & SDL_INIT_VIDEO)) { + if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_VIDEO)) { SDL_VideoQuit(); - SDL_initialized &= ~SDL_INIT_VIDEO; } + SDL_PrivateSubsystemRefCountDecr(SDL_INIT_VIDEO); } #endif + #if !SDL_TIMERS_DISABLED - if ((flags & SDL_initialized & SDL_INIT_TIMER)) { - SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_TIMER) ]--; - if ( SDL_bInMainQuit || SDL_SubsystemRefCount[ msb32_idx(SDL_INIT_TIMER) ] == 0 ) - { + if ((flags & SDL_INIT_TIMER)) { + if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_TIMER)) { SDL_TimerQuit(); - SDL_initialized &= ~SDL_INIT_TIMER; } + SDL_PrivateSubsystemRefCountDecr(SDL_INIT_TIMER); } #endif } @@ -271,16 +278,33 @@ SDL_QuitSubSystem(Uint32 flags) Uint32 SDL_WasInit(Uint32 flags) { + int i; + int num_subsystems = SDL_arraysize(SDL_SubsystemRefCount); + Uint32 initialized = 0; + if (!flags) { 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 SDL_Quit(void) { - SDL_bInMainQuit = SDL_TRUE; + SDL_bInMainQuit = SDL_TRUE; + /* Quit all subsystems */ #if defined(__WIN32__) SDL_HelperWindowDestroy(); @@ -294,8 +318,12 @@ SDL_Quit(void) SDL_AssertionsQuit(); SDL_LogResetPriorities(); - SDL_memset( SDL_SubsystemRefCount, 0x0, sizeof(SDL_SubsystemRefCount) ); - SDL_bInMainQuit = SDL_FALSE; + /* Now that every subsystem has been quit, we reset the subsystem refcount + * and the list of initialized subsystems. + */ + SDL_memset( SDL_SubsystemRefCount, 0x0, sizeof(SDL_SubsystemRefCount) ); + + SDL_bInMainQuit = SDL_FALSE; } /* Get the library version number */ diff --git a/test/Makefile.in b/test/Makefile.in index 5ebdd5e22..e54b29e37 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -70,6 +70,7 @@ testaudioinfo$(EXE): $(srcdir)/testaudioinfo.c testautomation$(EXE): $(srcdir)/testautomation.c \ $(srcdir)/testautomation_clipboard.c \ + $(srcdir)/testautomation_main.c \ $(srcdir)/testautomation_platform.c \ $(srcdir)/testautomation_rect.c \ $(srcdir)/testautomation_render.c \ diff --git a/test/testautomation_main.c b/test/testautomation_main.c new file mode 100644 index 000000000..c554b48be --- /dev/null +++ b/test/testautomation_main.c @@ -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: */ diff --git a/test/testautomation_suites.h b/test/testautomation_suites.h index c8c33a29f..2de9ae28e 100644 --- a/test/testautomation_suites.h +++ b/test/testautomation_suites.h @@ -13,6 +13,7 @@ extern SDLTest_TestSuiteReference audioTestSuite; extern SDLTest_TestSuiteReference clipboardTestSuite; extern SDLTest_TestSuiteReference eventsTestSuite; extern SDLTest_TestSuiteReference keyboardTestSuite; +extern SDLTest_TestSuiteReference mainTestSuite; extern SDLTest_TestSuiteReference platformTestSuite; extern SDLTest_TestSuiteReference rectTestSuite; extern SDLTest_TestSuiteReference renderTestSuite; @@ -30,6 +31,7 @@ SDLTest_TestSuiteReference *testSuites[] = { &clipboardTestSuite, &eventsTestSuite, &keyboardTestSuite, + &mainTestSuite, &platformTestSuite, &rectTestSuite, &renderTestSuite,