SDL

Форк
0
/
SDL.c 
757 строк · 22.5 Кб
1
/*
2
  Simple DirectMedia Layer
3
  Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
4

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.
8

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:
12

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.
20
*/
21
#include "SDL_internal.h"
22
#include "SDL3/SDL_revision.h"
23

24
#if defined(SDL_PLATFORM_WIN32) || defined(SDL_PLATFORM_GDK)
25
#include "core/windows/SDL_windows.h"
26
#elif !defined(SDL_PLATFORM_WINRT)
27
#include <unistd.h> // _exit(), etc.
28
#endif
29

30
// this checks for HAVE_DBUS_DBUS_H internally.
31
#include "core/linux/SDL_dbus.h"
32

33
#ifdef SDL_PLATFORM_EMSCRIPTEN
34
#include <emscripten.h>
35
#endif
36

37
// Initialization code for SDL
38

39
#include "SDL_assert_c.h"
40
#include "SDL_hints_c.h"
41
#include "SDL_log_c.h"
42
#include "SDL_properties_c.h"
43
#include "audio/SDL_sysaudio.h"
44
#include "camera/SDL_camera_c.h"
45
#include "cpuinfo/SDL_cpuinfo_c.h"
46
#include "events/SDL_events_c.h"
47
#include "haptic/SDL_haptic_c.h"
48
#include "joystick/SDL_gamepad_c.h"
49
#include "joystick/SDL_joystick_c.h"
50
#include "render/SDL_sysrender.h"
51
#include "sensor/SDL_sensor_c.h"
52
#include "thread/SDL_thread_c.h"
53
#include "video/SDL_pixels_c.h"
54
#include "video/SDL_video_c.h"
55
#include "filesystem/SDL_filesystem_c.h"
56

57
#define SDL_INIT_EVERYTHING ~0U
58

59
// Initialization/Cleanup routines
60
#include "timer/SDL_timer_c.h"
61
#ifdef SDL_VIDEO_DRIVER_WINDOWS
62
extern bool SDL_HelperWindowCreate(void);
63
extern void SDL_HelperWindowDestroy(void);
64
#endif
65

66
#ifdef SDL_BUILD_MAJOR_VERSION
67
SDL_COMPILE_TIME_ASSERT(SDL_BUILD_MAJOR_VERSION,
68
                        SDL_MAJOR_VERSION == SDL_BUILD_MAJOR_VERSION);
69
SDL_COMPILE_TIME_ASSERT(SDL_BUILD_MINOR_VERSION,
70
                        SDL_MINOR_VERSION == SDL_BUILD_MINOR_VERSION);
71
SDL_COMPILE_TIME_ASSERT(SDL_BUILD_MICRO_VERSION,
72
                        SDL_MICRO_VERSION == SDL_BUILD_MICRO_VERSION);
73
#endif
74

75
// Limited by its encoding in SDL_VERSIONNUM
76
SDL_COMPILE_TIME_ASSERT(SDL_MAJOR_VERSION_min, SDL_MAJOR_VERSION >= 0);
77
SDL_COMPILE_TIME_ASSERT(SDL_MAJOR_VERSION_max, SDL_MAJOR_VERSION <= 10);
78
SDL_COMPILE_TIME_ASSERT(SDL_MINOR_VERSION_min, SDL_MINOR_VERSION >= 0);
79
SDL_COMPILE_TIME_ASSERT(SDL_MINOR_VERSION_max, SDL_MINOR_VERSION <= 999);
80
SDL_COMPILE_TIME_ASSERT(SDL_MICRO_VERSION_min, SDL_MICRO_VERSION >= 0);
81
SDL_COMPILE_TIME_ASSERT(SDL_MICRO_VERSION_max, SDL_MICRO_VERSION <= 999);
82

83
/* This is not declared in any header, although it is shared between some
84
    parts of SDL, because we don't want anything calling it without an
85
    extremely good reason. */
86
extern SDL_NORETURN void SDL_ExitProcess(int exitcode);
87
SDL_NORETURN void SDL_ExitProcess(int exitcode)
88
{
89
#if defined(SDL_PLATFORM_WIN32) || defined(SDL_PLATFORM_GDK)
90
    /* "if you do not know the state of all threads in your process, it is
91
       better to call TerminateProcess than ExitProcess"
92
       https://msdn.microsoft.com/en-us/library/windows/desktop/ms682658(v=vs.85).aspx */
93
    TerminateProcess(GetCurrentProcess(), exitcode);
94
    /* MingW doesn't have TerminateProcess marked as noreturn, so add an
95
       ExitProcess here that will never be reached but make MingW happy. */
96
    ExitProcess(exitcode);
97
#elif defined(SDL_PLATFORM_EMSCRIPTEN)
98
    emscripten_cancel_main_loop();   // this should "kill" the app.
99
    emscripten_force_exit(exitcode); // this should "kill" the app.
100
    exit(exitcode);
101
#elif defined(SDL_PLATFORM_HAIKU)  // Haiku has _Exit, but it's not marked noreturn.
102
    _exit(exitcode);
103
#elif defined(HAVE__EXIT) // Upper case _Exit()
104
    _Exit(exitcode);
105
#else
106
    _exit(exitcode);
107
#endif
108
}
109

110
// App metadata
111

112
SDL_bool SDL_SetAppMetadata(const char *appname, const char *appversion, const char *appidentifier)
113
{
114
    SDL_SetAppMetadataProperty(SDL_PROP_APP_METADATA_NAME_STRING, appname);
115
    SDL_SetAppMetadataProperty(SDL_PROP_APP_METADATA_VERSION_STRING, appversion);
116
    SDL_SetAppMetadataProperty(SDL_PROP_APP_METADATA_IDENTIFIER_STRING, appidentifier);
117
    return true;
118
}
119

120
static bool SDL_ValidMetadataProperty(const char *name)
121
{
122
    if (!name || !*name) {
123
        return false;
124
    }
125

126
    if (SDL_strcmp(name, SDL_PROP_APP_METADATA_NAME_STRING) == 0 ||
127
        SDL_strcmp(name, SDL_PROP_APP_METADATA_VERSION_STRING) == 0 ||
128
        SDL_strcmp(name, SDL_PROP_APP_METADATA_IDENTIFIER_STRING) == 0 ||
129
        SDL_strcmp(name, SDL_PROP_APP_METADATA_CREATOR_STRING) == 0 ||
130
        SDL_strcmp(name, SDL_PROP_APP_METADATA_COPYRIGHT_STRING) == 0 ||
131
        SDL_strcmp(name, SDL_PROP_APP_METADATA_URL_STRING) == 0 ||
132
        SDL_strcmp(name, SDL_PROP_APP_METADATA_TYPE_STRING) == 0) {
133
        return true;
134
    }
135
    return false;
136
}
137

138
SDL_bool SDL_SetAppMetadataProperty(const char *name, const char *value)
139
{
140
    if (!SDL_ValidMetadataProperty(name)) {
141
        return SDL_InvalidParamError("name");
142
    }
143

144
    return SDL_SetStringProperty(SDL_GetGlobalProperties(), name, value);
145
}
146

147
const char *SDL_GetAppMetadataProperty(const char *name)
148
{
149
    if (!SDL_ValidMetadataProperty(name)) {
150
        SDL_InvalidParamError("name");
151
        return NULL;
152
    }
153

154
    const char *value = NULL;
155
    if (SDL_strcmp(name, SDL_PROP_APP_METADATA_NAME_STRING) == 0) {
156
        value = SDL_GetHint(SDL_HINT_APP_NAME);
157
    } else if (SDL_strcmp(name, SDL_PROP_APP_METADATA_IDENTIFIER_STRING) == 0) {
158
        value = SDL_GetHint(SDL_HINT_APP_ID);
159
    }
160
    if (!value || !*value) {
161
        value = SDL_GetStringProperty(SDL_GetGlobalProperties(), name, NULL);
162
    }
163
    if (!value || !*value) {
164
        if (SDL_strcmp(name, SDL_PROP_APP_METADATA_NAME_STRING) == 0) {
165
            value = "SDL Application";
166
        } else if (SDL_strcmp(name, SDL_PROP_APP_METADATA_TYPE_STRING) == 0) {
167
            value = "application";
168
        }
169
    }
170
    return value;
171
}
172

173

174
// The initialized subsystems
175
#ifdef SDL_MAIN_NEEDED
176
static bool SDL_MainIsReady = false;
177
#else
178
static bool SDL_MainIsReady = true;
179
#endif
180
static bool SDL_bInMainQuit = false;
181
static Uint8 SDL_SubsystemRefCount[32];
182

183
// Private helper to increment a subsystem's ref counter.
184
static void SDL_IncrementSubsystemRefCount(Uint32 subsystem)
185
{
186
    const int subsystem_index = SDL_MostSignificantBitIndex32(subsystem);
187
    SDL_assert((subsystem_index < 0) || (SDL_SubsystemRefCount[subsystem_index] < 255));
188
    if (subsystem_index >= 0) {
189
        ++SDL_SubsystemRefCount[subsystem_index];
190
    }
191
}
192

193
// Private helper to decrement a subsystem's ref counter.
194
static void SDL_DecrementSubsystemRefCount(Uint32 subsystem)
195
{
196
    const int subsystem_index = SDL_MostSignificantBitIndex32(subsystem);
197
    if ((subsystem_index >= 0) && (SDL_SubsystemRefCount[subsystem_index] > 0)) {
198
        if (SDL_bInMainQuit) {
199
            SDL_SubsystemRefCount[subsystem_index] = 0;
200
        } else {
201
            --SDL_SubsystemRefCount[subsystem_index];
202
        }
203
    }
204
}
205

206
// Private helper to check if a system needs init.
207
static bool SDL_ShouldInitSubsystem(Uint32 subsystem)
208
{
209
    const int subsystem_index = SDL_MostSignificantBitIndex32(subsystem);
210
    SDL_assert((subsystem_index < 0) || (SDL_SubsystemRefCount[subsystem_index] < 255));
211
    return ((subsystem_index >= 0) && (SDL_SubsystemRefCount[subsystem_index] == 0));
212
}
213

214
// Private helper to check if a system needs to be quit.
215
static bool SDL_ShouldQuitSubsystem(Uint32 subsystem)
216
{
217
    const int subsystem_index = SDL_MostSignificantBitIndex32(subsystem);
218
    if ((subsystem_index >= 0) && (SDL_SubsystemRefCount[subsystem_index] == 0)) {
219
        return false;
220
    }
221

222
    /* If we're in SDL_Quit, we shut down every subsystem, even if refcount
223
     * isn't zero.
224
     */
225
    return (((subsystem_index >= 0) && (SDL_SubsystemRefCount[subsystem_index] == 1)) || SDL_bInMainQuit);
226
}
227

228
/* Private helper to either increment's existing ref counter,
229
 * or fully init a new subsystem. */
230
static bool SDL_InitOrIncrementSubsystem(Uint32 subsystem)
231
{
232
    int subsystem_index = SDL_MostSignificantBitIndex32(subsystem);
233
    SDL_assert((subsystem_index < 0) || (SDL_SubsystemRefCount[subsystem_index] < 255));
234
    if (subsystem_index < 0) {
235
        return false;
236
    }
237
    if (SDL_SubsystemRefCount[subsystem_index] > 0) {
238
        ++SDL_SubsystemRefCount[subsystem_index];
239
        return true;
240
    }
241
    return SDL_InitSubSystem(subsystem);
242
}
243

244
void SDL_SetMainReady(void)
245
{
246
    SDL_MainIsReady = true;
247
}
248

249
// Initialize all the subsystems that require initialization before threads start
250
void SDL_InitMainThread(void)
251
{
252
    SDL_InitTLSData();
253
    SDL_InitTicks();
254
    SDL_InitFilesystem();
255
    SDL_InitLog();
256
    SDL_InitProperties();
257
    SDL_GetGlobalProperties();
258
    SDL_InitHints();
259
}
260

261
static void SDL_QuitMainThread(void)
262
{
263
    SDL_QuitHints();
264
    SDL_QuitProperties();
265
    SDL_QuitLog();
266
    SDL_QuitFilesystem();
267
    SDL_QuitTicks();
268
    SDL_QuitTLSData();
269
}
270

271
SDL_bool SDL_InitSubSystem(SDL_InitFlags flags)
272
{
273
    Uint32 flags_initialized = 0;
274

275
    if (!SDL_MainIsReady) {
276
        return SDL_SetError("Application didn't initialize properly, did you include SDL_main.h in the file containing your main() function?");
277
    }
278

279
    SDL_InitMainThread();
280

281
#ifdef SDL_USE_LIBDBUS
282
    SDL_DBus_Init();
283
#endif
284

285
#ifdef SDL_VIDEO_DRIVER_WINDOWS
286
    if (flags & (SDL_INIT_HAPTIC | SDL_INIT_JOYSTICK)) {
287
        if (!SDL_HelperWindowCreate()) {
288
            goto quit_and_error;
289
        }
290
    }
291
#endif
292

293
    // Initialize the event subsystem
294
    if (flags & SDL_INIT_EVENTS) {
295
        if (SDL_ShouldInitSubsystem(SDL_INIT_EVENTS)) {
296
            SDL_IncrementSubsystemRefCount(SDL_INIT_EVENTS);
297
            if (!SDL_InitEvents()) {
298
                SDL_DecrementSubsystemRefCount(SDL_INIT_EVENTS);
299
                goto quit_and_error;
300
            }
301
        } else {
302
            SDL_IncrementSubsystemRefCount(SDL_INIT_EVENTS);
303
        }
304
        flags_initialized |= SDL_INIT_EVENTS;
305
    }
306

307
    // Initialize the timer subsystem
308
    if (flags & SDL_INIT_TIMER) {
309
        if (SDL_ShouldInitSubsystem(SDL_INIT_TIMER)) {
310
            SDL_IncrementSubsystemRefCount(SDL_INIT_TIMER);
311
            if (!SDL_InitTimers()) {
312
                SDL_DecrementSubsystemRefCount(SDL_INIT_TIMER);
313
                goto quit_and_error;
314
            }
315
        } else {
316
            SDL_IncrementSubsystemRefCount(SDL_INIT_TIMER);
317
        }
318
        flags_initialized |= SDL_INIT_TIMER;
319
    }
320

321
    // Initialize the video subsystem
322
    if (flags & SDL_INIT_VIDEO) {
323
#ifndef SDL_VIDEO_DISABLED
324
        if (SDL_ShouldInitSubsystem(SDL_INIT_VIDEO)) {
325
            // video implies events
326
            if (!SDL_InitOrIncrementSubsystem(SDL_INIT_EVENTS)) {
327
                goto quit_and_error;
328
            }
329

330
            SDL_IncrementSubsystemRefCount(SDL_INIT_VIDEO);
331
            if (!SDL_VideoInit(NULL)) {
332
                SDL_DecrementSubsystemRefCount(SDL_INIT_VIDEO);
333
                goto quit_and_error;
334
            }
335
        } else {
336
            SDL_IncrementSubsystemRefCount(SDL_INIT_VIDEO);
337
        }
338
        flags_initialized |= SDL_INIT_VIDEO;
339
#else
340
        SDL_SetError("SDL not built with video support");
341
        goto quit_and_error;
342
#endif
343
    }
344

345
    // Initialize the audio subsystem
346
    if (flags & SDL_INIT_AUDIO) {
347
#ifndef SDL_AUDIO_DISABLED
348
        if (SDL_ShouldInitSubsystem(SDL_INIT_AUDIO)) {
349
            // audio implies events
350
            if (!SDL_InitOrIncrementSubsystem(SDL_INIT_EVENTS)) {
351
                goto quit_and_error;
352
            }
353

354
            SDL_IncrementSubsystemRefCount(SDL_INIT_AUDIO);
355
            if (!SDL_InitAudio(NULL)) {
356
                SDL_DecrementSubsystemRefCount(SDL_INIT_AUDIO);
357
                goto quit_and_error;
358
            }
359
        } else {
360
            SDL_IncrementSubsystemRefCount(SDL_INIT_AUDIO);
361
        }
362
        flags_initialized |= SDL_INIT_AUDIO;
363
#else
364
        SDL_SetError("SDL not built with audio support");
365
        goto quit_and_error;
366
#endif
367
    }
368

369
    // Initialize the joystick subsystem
370
    if (flags & SDL_INIT_JOYSTICK) {
371
#ifndef SDL_JOYSTICK_DISABLED
372
        if (SDL_ShouldInitSubsystem(SDL_INIT_JOYSTICK)) {
373
            // joystick implies events
374
            if (!SDL_InitOrIncrementSubsystem(SDL_INIT_EVENTS)) {
375
                goto quit_and_error;
376
            }
377

378
            SDL_IncrementSubsystemRefCount(SDL_INIT_JOYSTICK);
379
            if (!SDL_InitJoysticks()) {
380
                SDL_DecrementSubsystemRefCount(SDL_INIT_JOYSTICK);
381
                goto quit_and_error;
382
            }
383
        } else {
384
            SDL_IncrementSubsystemRefCount(SDL_INIT_JOYSTICK);
385
        }
386
        flags_initialized |= SDL_INIT_JOYSTICK;
387
#else
388
        SDL_SetError("SDL not built with joystick support");
389
        goto quit_and_error;
390
#endif
391
    }
392

393
    if (flags & SDL_INIT_GAMEPAD) {
394
#ifndef SDL_JOYSTICK_DISABLED
395
        if (SDL_ShouldInitSubsystem(SDL_INIT_GAMEPAD)) {
396
            // game controller implies joystick
397
            if (!SDL_InitOrIncrementSubsystem(SDL_INIT_JOYSTICK)) {
398
                goto quit_and_error;
399
            }
400

401
            SDL_IncrementSubsystemRefCount(SDL_INIT_GAMEPAD);
402
            if (!SDL_InitGamepads()) {
403
                SDL_DecrementSubsystemRefCount(SDL_INIT_GAMEPAD);
404
                goto quit_and_error;
405
            }
406
        } else {
407
            SDL_IncrementSubsystemRefCount(SDL_INIT_GAMEPAD);
408
        }
409
        flags_initialized |= SDL_INIT_GAMEPAD;
410
#else
411
        SDL_SetError("SDL not built with joystick support");
412
        goto quit_and_error;
413
#endif
414
    }
415

416
    // Initialize the haptic subsystem
417
    if (flags & SDL_INIT_HAPTIC) {
418
#ifndef SDL_HAPTIC_DISABLED
419
        if (SDL_ShouldInitSubsystem(SDL_INIT_HAPTIC)) {
420
            SDL_IncrementSubsystemRefCount(SDL_INIT_HAPTIC);
421
            if (!SDL_InitHaptics()) {
422
                SDL_DecrementSubsystemRefCount(SDL_INIT_HAPTIC);
423
                goto quit_and_error;
424
            }
425
        } else {
426
            SDL_IncrementSubsystemRefCount(SDL_INIT_HAPTIC);
427
        }
428
        flags_initialized |= SDL_INIT_HAPTIC;
429
#else
430
        SDL_SetError("SDL not built with haptic (force feedback) support");
431
        goto quit_and_error;
432
#endif
433
    }
434

435
    // Initialize the sensor subsystem
436
    if (flags & SDL_INIT_SENSOR) {
437
#ifndef SDL_SENSOR_DISABLED
438
        if (SDL_ShouldInitSubsystem(SDL_INIT_SENSOR)) {
439
            SDL_IncrementSubsystemRefCount(SDL_INIT_SENSOR);
440
            if (!SDL_InitSensors()) {
441
                SDL_DecrementSubsystemRefCount(SDL_INIT_SENSOR);
442
                goto quit_and_error;
443
            }
444
        } else {
445
            SDL_IncrementSubsystemRefCount(SDL_INIT_SENSOR);
446
        }
447
        flags_initialized |= SDL_INIT_SENSOR;
448
#else
449
        SDL_SetError("SDL not built with sensor support");
450
        goto quit_and_error;
451
#endif
452
    }
453

454
    // Initialize the camera subsystem
455
    if (flags & SDL_INIT_CAMERA) {
456
#ifndef SDL_CAMERA_DISABLED
457
        if (SDL_ShouldInitSubsystem(SDL_INIT_CAMERA)) {
458
            // camera implies events
459
            if (!SDL_InitOrIncrementSubsystem(SDL_INIT_EVENTS)) {
460
                goto quit_and_error;
461
            }
462

463
            SDL_IncrementSubsystemRefCount(SDL_INIT_CAMERA);
464
            if (!SDL_CameraInit(NULL)) {
465
                SDL_DecrementSubsystemRefCount(SDL_INIT_CAMERA);
466
                goto quit_and_error;
467
            }
468
        } else {
469
            SDL_IncrementSubsystemRefCount(SDL_INIT_CAMERA);
470
        }
471
        flags_initialized |= SDL_INIT_CAMERA;
472
#else
473
        SDL_SetError("SDL not built with camera support");
474
        goto quit_and_error;
475
#endif
476
    }
477

478
    (void)flags_initialized; // make static analysis happy, since this only gets used in error cases.
479

480
    return SDL_ClearError();
481

482
quit_and_error:
483
    SDL_QuitSubSystem(flags_initialized);
484
    return false;
485
}
486

487
SDL_bool SDL_Init(SDL_InitFlags flags)
488
{
489
    return SDL_InitSubSystem(flags);
490
}
491

492
void SDL_QuitSubSystem(SDL_InitFlags flags)
493
{
494
    // Shut down requested initialized subsystems
495

496
#ifndef SDL_CAMERA_DISABLED
497
    if (flags & SDL_INIT_CAMERA) {
498
        if (SDL_ShouldQuitSubsystem(SDL_INIT_CAMERA)) {
499
            SDL_QuitCamera();
500
            // camera implies events
501
            SDL_QuitSubSystem(SDL_INIT_EVENTS);
502
        }
503
        SDL_DecrementSubsystemRefCount(SDL_INIT_CAMERA);
504
    }
505
#endif
506

507
#ifndef SDL_SENSOR_DISABLED
508
    if (flags & SDL_INIT_SENSOR) {
509
        if (SDL_ShouldQuitSubsystem(SDL_INIT_SENSOR)) {
510
            SDL_QuitSensors();
511
        }
512
        SDL_DecrementSubsystemRefCount(SDL_INIT_SENSOR);
513
    }
514
#endif
515

516
#ifndef SDL_JOYSTICK_DISABLED
517
    if (flags & SDL_INIT_GAMEPAD) {
518
        if (SDL_ShouldQuitSubsystem(SDL_INIT_GAMEPAD)) {
519
            SDL_QuitGamepads();
520
            // game controller implies joystick
521
            SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
522
        }
523
        SDL_DecrementSubsystemRefCount(SDL_INIT_GAMEPAD);
524
    }
525

526
    if (flags & SDL_INIT_JOYSTICK) {
527
        if (SDL_ShouldQuitSubsystem(SDL_INIT_JOYSTICK)) {
528
            SDL_QuitJoysticks();
529
            // joystick implies events
530
            SDL_QuitSubSystem(SDL_INIT_EVENTS);
531
        }
532
        SDL_DecrementSubsystemRefCount(SDL_INIT_JOYSTICK);
533
    }
534
#endif
535

536
#ifndef SDL_HAPTIC_DISABLED
537
    if (flags & SDL_INIT_HAPTIC) {
538
        if (SDL_ShouldQuitSubsystem(SDL_INIT_HAPTIC)) {
539
            SDL_QuitHaptics();
540
        }
541
        SDL_DecrementSubsystemRefCount(SDL_INIT_HAPTIC);
542
    }
543
#endif
544

545
#ifndef SDL_AUDIO_DISABLED
546
    if (flags & SDL_INIT_AUDIO) {
547
        if (SDL_ShouldQuitSubsystem(SDL_INIT_AUDIO)) {
548
            SDL_QuitAudio();
549
            // audio implies events
550
            SDL_QuitSubSystem(SDL_INIT_EVENTS);
551
        }
552
        SDL_DecrementSubsystemRefCount(SDL_INIT_AUDIO);
553
    }
554
#endif
555

556
#ifndef SDL_VIDEO_DISABLED
557
    if (flags & SDL_INIT_VIDEO) {
558
        if (SDL_ShouldQuitSubsystem(SDL_INIT_VIDEO)) {
559
            SDL_QuitRender();
560
            SDL_VideoQuit();
561
            // video implies events
562
            SDL_QuitSubSystem(SDL_INIT_EVENTS);
563
        }
564
        SDL_DecrementSubsystemRefCount(SDL_INIT_VIDEO);
565
    }
566
#endif
567

568
    if (flags & SDL_INIT_TIMER) {
569
        if (SDL_ShouldQuitSubsystem(SDL_INIT_TIMER)) {
570
            SDL_QuitTimers();
571
        }
572
        SDL_DecrementSubsystemRefCount(SDL_INIT_TIMER);
573
    }
574

575
    if (flags & SDL_INIT_EVENTS) {
576
        if (SDL_ShouldQuitSubsystem(SDL_INIT_EVENTS)) {
577
            SDL_QuitEvents();
578
        }
579
        SDL_DecrementSubsystemRefCount(SDL_INIT_EVENTS);
580
    }
581
}
582

583
Uint32 SDL_WasInit(SDL_InitFlags flags)
584
{
585
    int i;
586
    int num_subsystems = SDL_arraysize(SDL_SubsystemRefCount);
587
    Uint32 initialized = 0;
588

589
    // Fast path for checking one flag
590
    if (SDL_HasExactlyOneBitSet32(flags)) {
591
        int subsystem_index = SDL_MostSignificantBitIndex32(flags);
592
        return SDL_SubsystemRefCount[subsystem_index] ? flags : 0;
593
    }
594

595
    if (!flags) {
596
        flags = SDL_INIT_EVERYTHING;
597
    }
598

599
    num_subsystems = SDL_min(num_subsystems, SDL_MostSignificantBitIndex32(flags) + 1);
600

601
    // Iterate over each bit in flags, and check the matching subsystem.
602
    for (i = 0; i < num_subsystems; ++i) {
603
        if ((flags & 1) && SDL_SubsystemRefCount[i] > 0) {
604
            initialized |= (1 << i);
605
        }
606

607
        flags >>= 1;
608
    }
609

610
    return initialized;
611
}
612

613
void SDL_Quit(void)
614
{
615
    SDL_bInMainQuit = true;
616

617
    // Quit all subsystems
618
#ifdef SDL_VIDEO_DRIVER_WINDOWS
619
    SDL_HelperWindowDestroy();
620
#endif
621
    SDL_QuitSubSystem(SDL_INIT_EVERYTHING);
622

623
#ifdef SDL_USE_LIBDBUS
624
    SDL_DBus_Quit();
625
#endif
626

627
    SDL_SetObjectsInvalid();
628
    SDL_AssertionsQuit();
629

630
    SDL_QuitPixelFormatDetails();
631

632
    SDL_QuitCPUInfo();
633

634
    /* Now that every subsystem has been quit, we reset the subsystem refcount
635
     * and the list of initialized subsystems.
636
     */
637
    SDL_memset(SDL_SubsystemRefCount, 0x0, sizeof(SDL_SubsystemRefCount));
638

639
    SDL_QuitMainThread();
640

641
    SDL_bInMainQuit = false;
642
}
643

644
// Get the library version number
645
int SDL_GetVersion(void)
646
{
647
    return SDL_VERSION;
648
}
649

650
// Get the library source revision
651
const char *SDL_GetRevision(void)
652
{
653
    return SDL_REVISION;
654
}
655

656
// Get the name of the platform
657
const char *SDL_GetPlatform(void)
658
{
659
#if defined(SDL_PLATFORM_AIX)
660
    return "AIX";
661
#elif defined(SDL_PLATFORM_ANDROID)
662
    return "Android";
663
#elif defined(SDL_PLATFORM_BSDI)
664
    return "BSDI";
665
#elif defined(SDL_PLATFORM_EMSCRIPTEN)
666
    return "Emscripten";
667
#elif defined(SDL_PLATFORM_FREEBSD)
668
    return "FreeBSD";
669
#elif defined(SDL_PLATFORM_HAIKU)
670
    return "Haiku";
671
#elif defined(SDL_PLATFORM_HPUX)
672
    return "HP-UX";
673
#elif defined(SDL_PLATFORM_IRIX)
674
    return "Irix";
675
#elif defined(SDL_PLATFORM_LINUX)
676
    return "Linux";
677
#elif defined(__MINT__)
678
    return "Atari MiNT";
679
#elif defined(SDL_PLATFORM_MACOS)
680
    return "macOS";
681
#elif defined(SDL_PLATFORM_NETBSD)
682
    return "NetBSD";
683
#elif defined(SDL_PLATFORM_OPENBSD)
684
    return "OpenBSD";
685
#elif defined(SDL_PLATFORM_OS2)
686
    return "OS/2";
687
#elif defined(SDL_PLATFORM_OSF)
688
    return "OSF/1";
689
#elif defined(SDL_PLATFORM_QNXNTO)
690
    return "QNX Neutrino";
691
#elif defined(SDL_PLATFORM_RISCOS)
692
    return "RISC OS";
693
#elif defined(SDL_PLATFORM_SOLARIS)
694
    return "Solaris";
695
#elif defined(SDL_PLATFORM_WIN32)
696
    return "Windows";
697
#elif defined(SDL_PLATFORM_WINRT)
698
    return "WinRT";
699
#elif defined(SDL_PLATFORM_WINGDK)
700
    return "WinGDK";
701
#elif defined(SDL_PLATFORM_XBOXONE)
702
    return "Xbox One";
703
#elif defined(SDL_PLATFORM_XBOXSERIES)
704
    return "Xbox Series X|S";
705
#elif defined(SDL_PLATFORM_IOS)
706
    return "iOS";
707
#elif defined(SDL_PLATFORM_TVOS)
708
    return "tvOS";
709
#elif defined(SDL_PLATFORM_PS2)
710
    return "PlayStation 2";
711
#elif defined(SDL_PLATFORM_PSP)
712
    return "PlayStation Portable";
713
#elif defined(SDL_PLATFORM_VITA)
714
    return "PlayStation Vita";
715
#elif defined(SDL_PLATFORM_NGAGE)
716
    return "Nokia N-Gage";
717
#elif defined(SDL_PLATFORM_3DS)
718
    return "Nintendo 3DS";
719
#elif defined(__managarm__)
720
    return "Managarm";
721
#else
722
    return "Unknown (see SDL_platform.h)";
723
#endif
724
}
725

726
SDL_bool SDL_IsTablet(void)
727
{
728
#ifdef SDL_PLATFORM_ANDROID
729
    extern bool SDL_IsAndroidTablet(void);
730
    return SDL_IsAndroidTablet();
731
#elif defined(SDL_PLATFORM_IOS)
732
    extern bool SDL_IsIPad(void);
733
    return SDL_IsIPad();
734
#else
735
    return false;
736
#endif
737
}
738

739
#ifdef SDL_PLATFORM_WIN32
740

741
#if (!defined(HAVE_LIBC) || defined(__WATCOMC__)) && !defined(SDL_STATIC_LIB)
742
// FIXME: Still need to include DllMain() on Watcom C ?
743

744
BOOL APIENTRY MINGW32_FORCEALIGN _DllMainCRTStartup(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
745
{
746
    switch (ul_reason_for_call) {
747
    case DLL_PROCESS_ATTACH:
748
    case DLL_THREAD_ATTACH:
749
    case DLL_THREAD_DETACH:
750
    case DLL_PROCESS_DETACH:
751
        break;
752
    }
753
    return TRUE;
754
}
755
#endif // Building DLL
756

757
#endif // defined(SDL_PLATFORM_WIN32) || defined(SDL_PLATFORM_GDK)
758

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.