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:
Jørgen P. Tjernø 2013-02-12 11:47:31 -08:00
parent 781ab3764f
commit f85aeb98c7
9 changed files with 411 additions and 140 deletions

View file

@ -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 \

View file

@ -375,6 +375,10 @@
RelativePath="..\..\include\SDL_audio.h"
>
</File>
<File
RelativePath="..\..\include\SDL_bits.h"
>
</File>
<File
RelativePath="..\..\include\SDL_blendmode.h"
>

View file

@ -207,6 +207,7 @@
<ClInclude Include="..\..\include\SDL_assert.h" />
<ClInclude Include="..\..\include\SDL_atomic.h" />
<ClInclude Include="..\..\include\SDL_audio.h" />
<ClInclude Include="..\..\include\SDL_bits.h" />
<ClInclude Include="..\..\include\SDL_blendmode.h" />
<ClInclude Include="..\..\include\SDL_clipboard.h" />
<ClInclude Include="..\..\include\SDL_config.h" />

View file

@ -211,6 +211,7 @@
<ClInclude Include="..\..\include\SDL_assert.h" />
<ClInclude Include="..\..\include\SDL_atomic.h" />
<ClInclude Include="..\..\include\SDL_audio.h" />
<ClInclude Include="..\..\include\SDL_bits.h" />
<ClInclude Include="..\..\include\SDL_blendmode.h" />
<ClInclude Include="..\..\include\SDL_clipboard.h" />
<ClInclude Include="..\..\include\SDL_config.h" />

102
include/SDL_bits.h Normal file
View 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: */

230
src/SDL.c
View file

@ -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];
}
#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 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);
}
/* 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)) {
/* Initialize the timer subsystem */
if (SDL_PrivateShouldInitSubsystem(flags, SDL_INIT_TIMER)) {
#if !SDL_TIMERS_DISABLED
if (SDL_TimerInit() < 0) {
return (-1);
}
SDL_initialized |= SDL_INIT_TIMER;
}
}
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_PrivateShouldInitSubsystem(flags, SDL_INIT_VIDEO)) {
#if !SDL_VIDEO_DISABLED
if (SDL_VideoInit(NULL) < 0) {
return (-1);
}
SDL_initialized |= SDL_INIT_VIDEO;
}
}
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_PrivateShouldInitSubsystem(flags, SDL_INIT_AUDIO)) {
#if !SDL_AUDIO_DISABLED
if (SDL_AudioInit(NULL) < 0) {
return (-1);
}
SDL_initialized |= SDL_INIT_AUDIO;
}
}
SDL_PrivateSubsystemRefCountIncr(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);
}
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)) {
// 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
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_initialized |= SDL_INIT_GAMECONTROLLER;
}
}
SDL_initialized |= SDL_INIT_JOYSTICK;
}
SDL_PrivateSubsystemRefCountIncr(SDL_INIT_GAMECONTROLLER);
#else
if (flags & SDL_INIT_JOYSTICK) {
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_PrivateShouldInitSubsystem(flags, SDL_INIT_HAPTIC)) {
#if !SDL_HAPTIC_DISABLED
if (SDL_HapticInit() < 0) {
return (-1);
}
SDL_initialized |= SDL_INIT_HAPTIC;
}
}
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 ) {
if ((flags & SDL_INIT_GAMECONTROLLER)) {
// Game controller implies Joystick.
flags |= SDL_INIT_JOYSTICK;
if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_GAMECONTROLLER)) {
SDL_GameControllerQuit();
SDL_initialized &= ~SDL_INIT_GAMECONTROLLER;
}
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
}
#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;
/* Quit all subsystems */
#if defined(__WIN32__)
SDL_HelperWindowDestroy();
@ -294,7 +318,11 @@ SDL_Quit(void)
SDL_AssertionsQuit();
SDL_LogResetPriorities();
/* 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;
}

View file

@ -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 \

131
test/testautomation_main.c Normal file
View 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: */

View file

@ -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,