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_atomic.h \
|
||||
SDL_audio.h \
|
||||
SDL_bits.h \
|
||||
SDL_blendmode.h \
|
||||
SDL_clipboard.h \
|
||||
SDL_cpuinfo.h \
|
||||
|
|
|
@ -375,6 +375,10 @@
|
|||
RelativePath="..\..\include\SDL_audio.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\include\SDL_bits.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\include\SDL_blendmode.h"
|
||||
>
|
||||
|
|
|
@ -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" />
|
||||
|
|
|
@ -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
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: */
|
230
src/SDL.c
230
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];
|
||||
}
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
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 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,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue