2 Simple DirectMedia Layer
3 Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
21 #include "./SDL_internal.h"
23 #if defined(__WIN32__)
24 #include "core/windows/SDL_windows.h"
27 /* Initialization code for SDL */
31 #include "SDL_revision.h"
32 #include "SDL_assert_c.h"
33 #include "events/SDL_events_c.h"
34 #include "haptic/SDL_haptic_c.h"
35 #include "joystick/SDL_joystick_c.h"
37 /* Initialization/Cleanup routines */
38 #if !SDL_TIMERS_DISABLED
39 # include "timer/SDL_timer_c.h"
41 #if SDL_VIDEO_DRIVER_WINDOWS
42 extern int SDL_HelperWindowCreate(void);
43 extern int SDL_HelperWindowDestroy(void);
47 /* The initialized subsystems */
48 #ifdef SDL_MAIN_NEEDED
49 static SDL_bool SDL_MainIsReady = SDL_FALSE;
51 static SDL_bool SDL_MainIsReady = SDL_TRUE;
53 static SDL_bool SDL_bInMainQuit = SDL_FALSE;
54 static Uint8 SDL_SubsystemRefCount[ 32 ];
56 /* Private helper to increment a subsystem's ref counter. */
58 SDL_PrivateSubsystemRefCountIncr(Uint32 subsystem)
60 int subsystem_index = SDL_MostSignificantBitIndex32(subsystem);
61 SDL_assert(SDL_SubsystemRefCount[subsystem_index] < 255);
62 ++SDL_SubsystemRefCount[subsystem_index];
65 /* Private helper to decrement a subsystem's ref counter. */
67 SDL_PrivateSubsystemRefCountDecr(Uint32 subsystem)
69 int subsystem_index = SDL_MostSignificantBitIndex32(subsystem);
70 if (SDL_SubsystemRefCount[subsystem_index] > 0) {
71 --SDL_SubsystemRefCount[subsystem_index];
75 /* Private helper to check if a system needs init. */
77 SDL_PrivateShouldInitSubsystem(Uint32 subsystem)
79 int subsystem_index = SDL_MostSignificantBitIndex32(subsystem);
80 SDL_assert(SDL_SubsystemRefCount[subsystem_index] < 255);
81 return (SDL_SubsystemRefCount[subsystem_index] == 0) ? SDL_TRUE : SDL_FALSE;
84 /* Private helper to check if a system needs to be quit. */
86 SDL_PrivateShouldQuitSubsystem(Uint32 subsystem) {
87 int subsystem_index = SDL_MostSignificantBitIndex32(subsystem);
88 if (SDL_SubsystemRefCount[subsystem_index] == 0) {
92 /* If we're in SDL_Quit, we shut down every subsystem, even if refcount
95 return (SDL_SubsystemRefCount[subsystem_index] == 1 || SDL_bInMainQuit) ? SDL_TRUE : SDL_FALSE;
99 SDL_SetMainReady(void)
101 SDL_MainIsReady = SDL_TRUE;
105 SDL_InitSubSystem(Uint32 flags)
107 if (!SDL_MainIsReady) {
108 SDL_SetError("Application didn't initialize properly, did you include SDL_main.h in the file containing your main() function?");
112 /* Clear the error message */
115 if ((flags & SDL_INIT_GAMECONTROLLER)) {
116 /* game controller implies joystick */
117 flags |= SDL_INIT_JOYSTICK;
120 if ((flags & (SDL_INIT_VIDEO|SDL_INIT_JOYSTICK))) {
121 /* video or joystick implies events */
122 flags |= SDL_INIT_EVENTS;
125 #if SDL_VIDEO_DRIVER_WINDOWS
126 if ((flags & (SDL_INIT_HAPTIC|SDL_INIT_JOYSTICK))) {
127 if (SDL_HelperWindowCreate() < 0) {
133 #if !SDL_TIMERS_DISABLED
137 /* Initialize the event subsystem */
138 if ((flags & SDL_INIT_EVENTS)) {
139 #if !SDL_EVENTS_DISABLED
140 if (SDL_PrivateShouldInitSubsystem(SDL_INIT_EVENTS)) {
141 if (SDL_StartEventLoop() < 0) {
146 SDL_PrivateSubsystemRefCountIncr(SDL_INIT_EVENTS);
148 return SDL_SetError("SDL not built with events support");
152 /* Initialize the timer subsystem */
153 if ((flags & SDL_INIT_TIMER)){
154 #if !SDL_TIMERS_DISABLED
155 if (SDL_PrivateShouldInitSubsystem(SDL_INIT_TIMER)) {
156 if (SDL_TimerInit() < 0) {
160 SDL_PrivateSubsystemRefCountIncr(SDL_INIT_TIMER);
162 return SDL_SetError("SDL not built with timer support");
166 /* Initialize the video subsystem */
167 if ((flags & SDL_INIT_VIDEO)){
168 #if !SDL_VIDEO_DISABLED
169 if (SDL_PrivateShouldInitSubsystem(SDL_INIT_VIDEO)) {
170 if (SDL_VideoInit(NULL) < 0) {
174 SDL_PrivateSubsystemRefCountIncr(SDL_INIT_VIDEO);
176 return SDL_SetError("SDL not built with video support");
180 /* Initialize the audio subsystem */
181 if ((flags & SDL_INIT_AUDIO)){
182 #if !SDL_AUDIO_DISABLED
183 if (SDL_PrivateShouldInitSubsystem(SDL_INIT_AUDIO)) {
184 if (SDL_AudioInit(NULL) < 0) {
188 SDL_PrivateSubsystemRefCountIncr(SDL_INIT_AUDIO);
190 return SDL_SetError("SDL not built with audio support");
194 /* Initialize the joystick subsystem */
195 if ((flags & SDL_INIT_JOYSTICK)){
196 #if !SDL_JOYSTICK_DISABLED
197 if (SDL_PrivateShouldInitSubsystem(SDL_INIT_JOYSTICK)) {
198 if (SDL_JoystickInit() < 0) {
202 SDL_PrivateSubsystemRefCountIncr(SDL_INIT_JOYSTICK);
204 return SDL_SetError("SDL not built with joystick support");
208 if ((flags & SDL_INIT_GAMECONTROLLER)){
209 #if !SDL_JOYSTICK_DISABLED
210 if (SDL_PrivateShouldInitSubsystem(SDL_INIT_GAMECONTROLLER)) {
211 if (SDL_GameControllerInit() < 0) {
215 SDL_PrivateSubsystemRefCountIncr(SDL_INIT_GAMECONTROLLER);
217 return SDL_SetError("SDL not built with joystick support");
221 /* Initialize the haptic subsystem */
222 if ((flags & SDL_INIT_HAPTIC)){
223 #if !SDL_HAPTIC_DISABLED
224 if (SDL_PrivateShouldInitSubsystem(SDL_INIT_HAPTIC)) {
225 if (SDL_HapticInit() < 0) {
229 SDL_PrivateSubsystemRefCountIncr(SDL_INIT_HAPTIC);
231 return SDL_SetError("SDL not built with haptic (force feedback) support");
239 SDL_Init(Uint32 flags)
241 return SDL_InitSubSystem(flags);
245 SDL_QuitSubSystem(Uint32 flags)
247 /* Shut down requested initialized subsystems */
248 #if !SDL_JOYSTICK_DISABLED
249 if ((flags & SDL_INIT_GAMECONTROLLER)) {
250 /* game controller implies joystick */
251 flags |= SDL_INIT_JOYSTICK;
253 if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_GAMECONTROLLER)) {
254 SDL_GameControllerQuit();
256 SDL_PrivateSubsystemRefCountDecr(SDL_INIT_GAMECONTROLLER);
259 if ((flags & SDL_INIT_JOYSTICK)) {
260 /* joystick implies events */
261 flags |= SDL_INIT_EVENTS;
263 if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_JOYSTICK)) {
266 SDL_PrivateSubsystemRefCountDecr(SDL_INIT_JOYSTICK);
270 #if !SDL_HAPTIC_DISABLED
271 if ((flags & SDL_INIT_HAPTIC)) {
272 if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_HAPTIC)) {
275 SDL_PrivateSubsystemRefCountDecr(SDL_INIT_HAPTIC);
279 #if !SDL_AUDIO_DISABLED
280 if ((flags & SDL_INIT_AUDIO)) {
281 if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_AUDIO)) {
284 SDL_PrivateSubsystemRefCountDecr(SDL_INIT_AUDIO);
288 #if !SDL_VIDEO_DISABLED
289 if ((flags & SDL_INIT_VIDEO)) {
290 /* video implies events */
291 flags |= SDL_INIT_EVENTS;
293 if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_VIDEO)) {
296 SDL_PrivateSubsystemRefCountDecr(SDL_INIT_VIDEO);
300 #if !SDL_TIMERS_DISABLED
301 if ((flags & SDL_INIT_TIMER)) {
302 if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_TIMER)) {
305 SDL_PrivateSubsystemRefCountDecr(SDL_INIT_TIMER);
309 #if !SDL_EVENTS_DISABLED
310 if ((flags & SDL_INIT_EVENTS)) {
311 if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_EVENTS)) {
315 SDL_PrivateSubsystemRefCountDecr(SDL_INIT_EVENTS);
321 SDL_WasInit(Uint32 flags)
324 int num_subsystems = SDL_arraysize(SDL_SubsystemRefCount);
325 Uint32 initialized = 0;
328 flags = SDL_INIT_EVERYTHING;
331 num_subsystems = SDL_min(num_subsystems, SDL_MostSignificantBitIndex32(flags) + 1);
333 /* Iterate over each bit in flags, and check the matching subsystem. */
334 for (i = 0; i < num_subsystems; ++i) {
335 if ((flags & 1) && SDL_SubsystemRefCount[i] > 0) {
336 initialized |= (1 << i);
348 SDL_bInMainQuit = SDL_TRUE;
350 /* Quit all subsystems */
351 #if SDL_VIDEO_DRIVER_WINDOWS
352 SDL_HelperWindowDestroy();
354 SDL_QuitSubSystem(SDL_INIT_EVERYTHING);
356 #if !SDL_TIMERS_DISABLED
361 SDL_AssertionsQuit();
362 SDL_LogResetPriorities();
364 /* Now that every subsystem has been quit, we reset the subsystem refcount
365 * and the list of initialized subsystems.
367 SDL_memset( SDL_SubsystemRefCount, 0x0, sizeof(SDL_SubsystemRefCount) );
369 SDL_bInMainQuit = SDL_FALSE;
372 /* Get the library version number */
374 SDL_GetVersion(SDL_version * ver)
379 /* Get the library source revision */
381 SDL_GetRevision(void)
386 /* Get the library source revision number */
388 SDL_GetRevisionNumber(void)
390 return SDL_REVISION_NUMBER;
393 /* Get the name of the platform */
420 return "MacOS Classic";
434 return "QNX Neutrino";
448 return "PlayStation Portable";
452 return "Unknown (see SDL_platform.h)";
456 #if defined(__WIN32__)
458 #if (!defined(HAVE_LIBC) || defined(__WATCOMC__)) && !defined(SDL_STATIC_LIB)
459 /* Need to include DllMain() on Watcom C for some reason.. */
462 _DllMainCRTStartup(HANDLE hModule,
463 DWORD ul_reason_for_call, LPVOID lpReserved)
465 switch (ul_reason_for_call) {
466 case DLL_PROCESS_ATTACH:
467 case DLL_THREAD_ATTACH:
468 case DLL_THREAD_DETACH:
469 case DLL_PROCESS_DETACH:
474 #endif /* Building DLL */
476 #endif /* __WIN32__ */
478 /* vi: set sts=4 ts=4 sw=4 expandtab: */