Convert ticks to 64-bit, added nanosecond precision to the API

Fixes https://github.com/libsdl-org/SDL/issues/5512
Fixes https://github.com/libsdl-org/SDL/issues/6731
This commit is contained in:
Sam Lantinga
2022-12-02 01:17:17 -08:00
parent 764b899a13
commit 8121bbd083
96 changed files with 938 additions and 1243 deletions
+7 -1
View File
@@ -32,4 +32,10 @@ General:
* Added SDL_CreateSurface() and SDL_CreateSurfaceFrom() which replace the SDL_CreateRGBSurface*() * Added SDL_CreateSurface() and SDL_CreateSurfaceFrom() which replace the SDL_CreateRGBSurface*()
* Removed unused 'flags' parameter from SDL_ConvertSurface and SDL_ConvertSurfaceFormat * Removed unused 'flags' parameter from SDL_ConvertSurface and SDL_ConvertSurfaceFormat
* Removed 'SDL_GL_CONTEXT_EGL' from OpenGL configuration attributes * Removed 'SDL_GL_CONTEXT_EGL' from OpenGL configuration attributes
* SDL_GetTicks() now returns a 64-bit value and the tick values should be directly compared instead of using the SDL_TICKS_PASSED macro
* Added SDL_GetTicksNS() to return the number of nanoseconds since the SDL library initialized
* Added SDL_DelayNS() to specify a delay in nanoseconds, to the highest precision the system will support
* Added SDL_WaitEventTimeoutNS() to wait for events with the highest possible precision
* Added SDL_SemWaitTimeoutNS() to wait for a semaphore with the highest possible precision
* Added SDL_CondWaitTimeoutNS() to wait for a condition variable the highest possible precision
* The timestamp member of the SDL_Event structure is now in nanoseconds, filled in with SDL_GetTicksNS()
+28
View File
@@ -31,6 +31,10 @@ LDFLAGS += $(shell pkg-config sdl3 --libs)
The SDL3main and SDL3test libraries have been renamed SDL3_main and SDL3_test, respectively. The SDL3main and SDL3test libraries have been renamed SDL3_main and SDL3_test, respectively.
## SDL_events.h
The `timestamp` member of the SDL_Event structure now represents nanoseconds, and is populated with `SDL_GetTicksNS()`
## SDL_platform.h ## SDL_platform.h
The preprocessor symbol __MACOSX__ has been renamed __MACOS__, and __IPHONEOS__ has been renamed __IOS__ The preprocessor symbol __MACOSX__ has been renamed __MACOS__, and __IPHONEOS__ has been renamed __IOS__
@@ -223,6 +227,30 @@ The structures in this file are versioned separately from the rest of SDL, allow
This function now returns a standard int result instead of SDL_bool, returning 0 if the function succeeds or a negative error code if there was an error. You should also pass `SDL_SYSWM_CURRENT_VERSION` as the new third version parameter. The version member of the info structure will be filled in with the version of data that is returned, the minimum of the version you requested and the version supported by the runtime SDL library. This function now returns a standard int result instead of SDL_bool, returning 0 if the function succeeds or a negative error code if there was an error. You should also pass `SDL_SYSWM_CURRENT_VERSION` as the new third version parameter. The version member of the info structure will be filled in with the version of data that is returned, the minimum of the version you requested and the version supported by the runtime SDL library.
## SDL_timer.h
SDL_GetTicks() now returns a 64-bit value. Instead of using the `SDL_TICKS_PASSED` macro, you can directly compare tick values, e.g.
```c
Uint32 deadline = SDL_GetTicks() + 1000;
...
if (SDL_TICKS_PASSED(SDL_GetTicks(), deadline)) {
...
}
```
becomes:
```c
Uint64 deadline = SDL_GetTicks() + 1000
...
if (SDL_GetTicks() >= deadline) {
...
}
```
If you were using this macro for other things besides SDL ticks values, you can define it in your own code as:
```c
#define SDL_TICKS_PASSED(A, B) ((Sint32)((B) - (A)) <= 0)
```
## SDL_version.h ## SDL_version.h
SDL_GetRevisionNumber() has been removed from the API, it always returned 0 in SDL 2.0 SDL_GetRevisionNumber() has been removed from the API, it always returned 0 in SDL 2.0
+72 -37
View File
@@ -182,7 +182,7 @@ typedef enum
typedef struct SDL_CommonEvent typedef struct SDL_CommonEvent
{ {
Uint32 type; Uint32 type;
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
} SDL_CommonEvent; } SDL_CommonEvent;
/** /**
@@ -191,7 +191,7 @@ typedef struct SDL_CommonEvent
typedef struct SDL_DisplayEvent typedef struct SDL_DisplayEvent
{ {
Uint32 type; /**< ::SDL_DISPLAYEVENT */ Uint32 type; /**< ::SDL_DISPLAYEVENT */
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
Uint32 display; /**< The associated display index */ Uint32 display; /**< The associated display index */
Uint8 event; /**< ::SDL_DisplayEventID */ Uint8 event; /**< ::SDL_DisplayEventID */
Uint8 padding1; Uint8 padding1;
@@ -206,7 +206,7 @@ typedef struct SDL_DisplayEvent
typedef struct SDL_WindowEvent typedef struct SDL_WindowEvent
{ {
Uint32 type; /**< ::SDL_WINDOWEVENT */ Uint32 type; /**< ::SDL_WINDOWEVENT */
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
Uint32 windowID; /**< The associated window */ Uint32 windowID; /**< The associated window */
Uint8 event; /**< ::SDL_WindowEventID */ Uint8 event; /**< ::SDL_WindowEventID */
Uint8 padding1; Uint8 padding1;
@@ -222,7 +222,7 @@ typedef struct SDL_WindowEvent
typedef struct SDL_KeyboardEvent typedef struct SDL_KeyboardEvent
{ {
Uint32 type; /**< ::SDL_KEYDOWN or ::SDL_KEYUP */ Uint32 type; /**< ::SDL_KEYDOWN or ::SDL_KEYUP */
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
Uint32 windowID; /**< The window with keyboard focus, if any */ Uint32 windowID; /**< The window with keyboard focus, if any */
Uint8 state; /**< ::SDL_PRESSED or ::SDL_RELEASED */ Uint8 state; /**< ::SDL_PRESSED or ::SDL_RELEASED */
Uint8 repeat; /**< Non-zero if this is a key repeat */ Uint8 repeat; /**< Non-zero if this is a key repeat */
@@ -238,7 +238,7 @@ typedef struct SDL_KeyboardEvent
typedef struct SDL_TextEditingEvent typedef struct SDL_TextEditingEvent
{ {
Uint32 type; /**< ::SDL_TEXTEDITING */ Uint32 type; /**< ::SDL_TEXTEDITING */
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
Uint32 windowID; /**< The window with keyboard focus, if any */ Uint32 windowID; /**< The window with keyboard focus, if any */
char text[SDL_TEXTEDITINGEVENT_TEXT_SIZE]; /**< The editing text */ char text[SDL_TEXTEDITINGEVENT_TEXT_SIZE]; /**< The editing text */
Sint32 start; /**< The start cursor of selected editing text */ Sint32 start; /**< The start cursor of selected editing text */
@@ -252,7 +252,7 @@ typedef struct SDL_TextEditingEvent
typedef struct SDL_TextEditingExtEvent typedef struct SDL_TextEditingExtEvent
{ {
Uint32 type; /**< ::SDL_TEXTEDITING_EXT */ Uint32 type; /**< ::SDL_TEXTEDITING_EXT */
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
Uint32 windowID; /**< The window with keyboard focus, if any */ Uint32 windowID; /**< The window with keyboard focus, if any */
char* text; /**< The editing text, which should be freed with SDL_free(), and will not be NULL */ char* text; /**< The editing text, which should be freed with SDL_free(), and will not be NULL */
Sint32 start; /**< The start cursor of selected editing text */ Sint32 start; /**< The start cursor of selected editing text */
@@ -266,7 +266,7 @@ typedef struct SDL_TextEditingExtEvent
typedef struct SDL_TextInputEvent typedef struct SDL_TextInputEvent
{ {
Uint32 type; /**< ::SDL_TEXTINPUT */ Uint32 type; /**< ::SDL_TEXTINPUT */
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
Uint32 windowID; /**< The window with keyboard focus, if any */ Uint32 windowID; /**< The window with keyboard focus, if any */
char text[SDL_TEXTINPUTEVENT_TEXT_SIZE]; /**< The input text */ char text[SDL_TEXTINPUTEVENT_TEXT_SIZE]; /**< The input text */
} SDL_TextInputEvent; } SDL_TextInputEvent;
@@ -277,7 +277,7 @@ typedef struct SDL_TextInputEvent
typedef struct SDL_MouseMotionEvent typedef struct SDL_MouseMotionEvent
{ {
Uint32 type; /**< ::SDL_MOUSEMOTION */ Uint32 type; /**< ::SDL_MOUSEMOTION */
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
Uint32 windowID; /**< The window with mouse focus, if any */ Uint32 windowID; /**< The window with mouse focus, if any */
Uint32 which; /**< The mouse instance id, or SDL_TOUCH_MOUSEID */ Uint32 which; /**< The mouse instance id, or SDL_TOUCH_MOUSEID */
Uint32 state; /**< The current button state */ Uint32 state; /**< The current button state */
@@ -293,7 +293,7 @@ typedef struct SDL_MouseMotionEvent
typedef struct SDL_MouseButtonEvent typedef struct SDL_MouseButtonEvent
{ {
Uint32 type; /**< ::SDL_MOUSEBUTTONDOWN or ::SDL_MOUSEBUTTONUP */ Uint32 type; /**< ::SDL_MOUSEBUTTONDOWN or ::SDL_MOUSEBUTTONUP */
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
Uint32 windowID; /**< The window with mouse focus, if any */ Uint32 windowID; /**< The window with mouse focus, if any */
SDL_MouseID which; /**< The mouse instance id, or SDL_TOUCH_MOUSEID */ SDL_MouseID which; /**< The mouse instance id, or SDL_TOUCH_MOUSEID */
Uint8 button; /**< The mouse button index */ Uint8 button; /**< The mouse button index */
@@ -310,7 +310,7 @@ typedef struct SDL_MouseButtonEvent
typedef struct SDL_MouseWheelEvent typedef struct SDL_MouseWheelEvent
{ {
Uint32 type; /**< ::SDL_MOUSEWHEEL */ Uint32 type; /**< ::SDL_MOUSEWHEEL */
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
Uint32 windowID; /**< The window with mouse focus, if any */ Uint32 windowID; /**< The window with mouse focus, if any */
SDL_MouseID which; /**< The mouse instance id, or SDL_TOUCH_MOUSEID */ SDL_MouseID which; /**< The mouse instance id, or SDL_TOUCH_MOUSEID */
Sint32 x; /**< The amount scrolled horizontally, positive to the right and negative to the left */ Sint32 x; /**< The amount scrolled horizontally, positive to the right and negative to the left */
@@ -328,7 +328,7 @@ typedef struct SDL_MouseWheelEvent
typedef struct SDL_JoyAxisEvent typedef struct SDL_JoyAxisEvent
{ {
Uint32 type; /**< ::SDL_JOYAXISMOTION */ Uint32 type; /**< ::SDL_JOYAXISMOTION */
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
SDL_JoystickID which; /**< The joystick instance id */ SDL_JoystickID which; /**< The joystick instance id */
Uint8 axis; /**< The joystick axis index */ Uint8 axis; /**< The joystick axis index */
Uint8 padding1; Uint8 padding1;
@@ -344,7 +344,7 @@ typedef struct SDL_JoyAxisEvent
typedef struct SDL_JoyBallEvent typedef struct SDL_JoyBallEvent
{ {
Uint32 type; /**< ::SDL_JOYBALLMOTION */ Uint32 type; /**< ::SDL_JOYBALLMOTION */
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
SDL_JoystickID which; /**< The joystick instance id */ SDL_JoystickID which; /**< The joystick instance id */
Uint8 ball; /**< The joystick trackball index */ Uint8 ball; /**< The joystick trackball index */
Uint8 padding1; Uint8 padding1;
@@ -360,7 +360,7 @@ typedef struct SDL_JoyBallEvent
typedef struct SDL_JoyHatEvent typedef struct SDL_JoyHatEvent
{ {
Uint32 type; /**< ::SDL_JOYHATMOTION */ Uint32 type; /**< ::SDL_JOYHATMOTION */
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
SDL_JoystickID which; /**< The joystick instance id */ SDL_JoystickID which; /**< The joystick instance id */
Uint8 hat; /**< The joystick hat index */ Uint8 hat; /**< The joystick hat index */
Uint8 value; /**< The hat position value. Uint8 value; /**< The hat position value.
@@ -380,7 +380,7 @@ typedef struct SDL_JoyHatEvent
typedef struct SDL_JoyButtonEvent typedef struct SDL_JoyButtonEvent
{ {
Uint32 type; /**< ::SDL_JOYBUTTONDOWN or ::SDL_JOYBUTTONUP */ Uint32 type; /**< ::SDL_JOYBUTTONDOWN or ::SDL_JOYBUTTONUP */
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
SDL_JoystickID which; /**< The joystick instance id */ SDL_JoystickID which; /**< The joystick instance id */
Uint8 button; /**< The joystick button index */ Uint8 button; /**< The joystick button index */
Uint8 state; /**< ::SDL_PRESSED or ::SDL_RELEASED */ Uint8 state; /**< ::SDL_PRESSED or ::SDL_RELEASED */
@@ -394,7 +394,7 @@ typedef struct SDL_JoyButtonEvent
typedef struct SDL_JoyDeviceEvent typedef struct SDL_JoyDeviceEvent
{ {
Uint32 type; /**< ::SDL_JOYDEVICEADDED or ::SDL_JOYDEVICEREMOVED */ Uint32 type; /**< ::SDL_JOYDEVICEADDED or ::SDL_JOYDEVICEREMOVED */
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
SDL_JoystickID which; /**< The joystick device index for the ADDED event, instance id for the REMOVED event */ SDL_JoystickID which; /**< The joystick device index for the ADDED event, instance id for the REMOVED event */
} SDL_JoyDeviceEvent; } SDL_JoyDeviceEvent;
@@ -404,7 +404,7 @@ typedef struct SDL_JoyDeviceEvent
typedef struct SDL_JoyBatteryEvent typedef struct SDL_JoyBatteryEvent
{ {
Uint32 type; /**< ::SDL_JOYBATTERYUPDATED */ Uint32 type; /**< ::SDL_JOYBATTERYUPDATED */
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
SDL_JoystickID which; /**< The joystick instance id */ SDL_JoystickID which; /**< The joystick instance id */
SDL_JoystickPowerLevel level; /**< The joystick battery level */ SDL_JoystickPowerLevel level; /**< The joystick battery level */
} SDL_JoyBatteryEvent; } SDL_JoyBatteryEvent;
@@ -415,7 +415,7 @@ typedef struct SDL_JoyBatteryEvent
typedef struct SDL_ControllerAxisEvent typedef struct SDL_ControllerAxisEvent
{ {
Uint32 type; /**< ::SDL_CONTROLLERAXISMOTION */ Uint32 type; /**< ::SDL_CONTROLLERAXISMOTION */
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
SDL_JoystickID which; /**< The joystick instance id */ SDL_JoystickID which; /**< The joystick instance id */
Uint8 axis; /**< The controller axis (SDL_GameControllerAxis) */ Uint8 axis; /**< The controller axis (SDL_GameControllerAxis) */
Uint8 padding1; Uint8 padding1;
@@ -432,7 +432,7 @@ typedef struct SDL_ControllerAxisEvent
typedef struct SDL_ControllerButtonEvent typedef struct SDL_ControllerButtonEvent
{ {
Uint32 type; /**< ::SDL_CONTROLLERBUTTONDOWN or ::SDL_CONTROLLERBUTTONUP */ Uint32 type; /**< ::SDL_CONTROLLERBUTTONDOWN or ::SDL_CONTROLLERBUTTONUP */
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
SDL_JoystickID which; /**< The joystick instance id */ SDL_JoystickID which; /**< The joystick instance id */
Uint8 button; /**< The controller button (SDL_GameControllerButton) */ Uint8 button; /**< The controller button (SDL_GameControllerButton) */
Uint8 state; /**< ::SDL_PRESSED or ::SDL_RELEASED */ Uint8 state; /**< ::SDL_PRESSED or ::SDL_RELEASED */
@@ -447,7 +447,7 @@ typedef struct SDL_ControllerButtonEvent
typedef struct SDL_ControllerDeviceEvent typedef struct SDL_ControllerDeviceEvent
{ {
Uint32 type; /**< ::SDL_CONTROLLERDEVICEADDED, ::SDL_CONTROLLERDEVICEREMOVED, or ::SDL_CONTROLLERDEVICEREMAPPED */ Uint32 type; /**< ::SDL_CONTROLLERDEVICEADDED, ::SDL_CONTROLLERDEVICEREMOVED, or ::SDL_CONTROLLERDEVICEREMAPPED */
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
SDL_JoystickID which; /**< The joystick device index for the ADDED event, instance id for the REMOVED or REMAPPED event */ SDL_JoystickID which; /**< The joystick device index for the ADDED event, instance id for the REMOVED or REMAPPED event */
} SDL_ControllerDeviceEvent; } SDL_ControllerDeviceEvent;
@@ -457,7 +457,7 @@ typedef struct SDL_ControllerDeviceEvent
typedef struct SDL_ControllerTouchpadEvent typedef struct SDL_ControllerTouchpadEvent
{ {
Uint32 type; /**< ::SDL_CONTROLLERTOUCHPADDOWN or ::SDL_CONTROLLERTOUCHPADMOTION or ::SDL_CONTROLLERTOUCHPADUP */ Uint32 type; /**< ::SDL_CONTROLLERTOUCHPADDOWN or ::SDL_CONTROLLERTOUCHPADMOTION or ::SDL_CONTROLLERTOUCHPADUP */
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
SDL_JoystickID which; /**< The joystick instance id */ SDL_JoystickID which; /**< The joystick instance id */
Sint32 touchpad; /**< The index of the touchpad */ Sint32 touchpad; /**< The index of the touchpad */
Sint32 finger; /**< The index of the finger on the touchpad */ Sint32 finger; /**< The index of the finger on the touchpad */
@@ -472,7 +472,7 @@ typedef struct SDL_ControllerTouchpadEvent
typedef struct SDL_ControllerSensorEvent typedef struct SDL_ControllerSensorEvent
{ {
Uint32 type; /**< ::SDL_CONTROLLERSENSORUPDATE */ Uint32 type; /**< ::SDL_CONTROLLERSENSORUPDATE */
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
SDL_JoystickID which; /**< The joystick instance id */ SDL_JoystickID which; /**< The joystick instance id */
Sint32 sensor; /**< The type of the sensor, one of the values of ::SDL_SensorType */ Sint32 sensor; /**< The type of the sensor, one of the values of ::SDL_SensorType */
float data[3]; /**< Up to 3 values from the sensor, as defined in SDL_sensor.h */ float data[3]; /**< Up to 3 values from the sensor, as defined in SDL_sensor.h */
@@ -485,7 +485,7 @@ typedef struct SDL_ControllerSensorEvent
typedef struct SDL_AudioDeviceEvent typedef struct SDL_AudioDeviceEvent
{ {
Uint32 type; /**< ::SDL_AUDIODEVICEADDED, or ::SDL_AUDIODEVICEREMOVED */ Uint32 type; /**< ::SDL_AUDIODEVICEADDED, or ::SDL_AUDIODEVICEREMOVED */
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
Uint32 which; /**< The audio device index for the ADDED event (valid until next SDL_GetNumAudioDevices() call), SDL_AudioDeviceID for the REMOVED event */ Uint32 which; /**< The audio device index for the ADDED event (valid until next SDL_GetNumAudioDevices() call), SDL_AudioDeviceID for the REMOVED event */
Uint8 iscapture; /**< zero if an output device, non-zero if a capture device. */ Uint8 iscapture; /**< zero if an output device, non-zero if a capture device. */
Uint8 padding1; Uint8 padding1;
@@ -500,7 +500,7 @@ typedef struct SDL_AudioDeviceEvent
typedef struct SDL_TouchFingerEvent typedef struct SDL_TouchFingerEvent
{ {
Uint32 type; /**< ::SDL_FINGERMOTION or ::SDL_FINGERDOWN or ::SDL_FINGERUP */ Uint32 type; /**< ::SDL_FINGERMOTION or ::SDL_FINGERDOWN or ::SDL_FINGERUP */
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
SDL_TouchID touchId; /**< The touch device id */ SDL_TouchID touchId; /**< The touch device id */
SDL_FingerID fingerId; SDL_FingerID fingerId;
float x; /**< Normalized in the range 0...1 */ float x; /**< Normalized in the range 0...1 */
@@ -518,7 +518,7 @@ typedef struct SDL_TouchFingerEvent
typedef struct SDL_MultiGestureEvent typedef struct SDL_MultiGestureEvent
{ {
Uint32 type; /**< ::SDL_MULTIGESTURE */ Uint32 type; /**< ::SDL_MULTIGESTURE */
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
SDL_TouchID touchId; /**< The touch device id */ SDL_TouchID touchId; /**< The touch device id */
float dTheta; float dTheta;
float dDist; float dDist;
@@ -535,7 +535,7 @@ typedef struct SDL_MultiGestureEvent
typedef struct SDL_DollarGestureEvent typedef struct SDL_DollarGestureEvent
{ {
Uint32 type; /**< ::SDL_DOLLARGESTURE or ::SDL_DOLLARRECORD */ Uint32 type; /**< ::SDL_DOLLARGESTURE or ::SDL_DOLLARRECORD */
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
SDL_TouchID touchId; /**< The touch device id */ SDL_TouchID touchId; /**< The touch device id */
SDL_GestureID gestureId; SDL_GestureID gestureId;
Uint32 numFingers; Uint32 numFingers;
@@ -553,7 +553,7 @@ typedef struct SDL_DollarGestureEvent
typedef struct SDL_DropEvent typedef struct SDL_DropEvent
{ {
Uint32 type; /**< ::SDL_DROPBEGIN or ::SDL_DROPFILE or ::SDL_DROPTEXT or ::SDL_DROPCOMPLETE */ Uint32 type; /**< ::SDL_DROPBEGIN or ::SDL_DROPFILE or ::SDL_DROPTEXT or ::SDL_DROPCOMPLETE */
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
char *file; /**< The file name, which should be freed with SDL_free(), is NULL on begin/complete */ char *file; /**< The file name, which should be freed with SDL_free(), is NULL on begin/complete */
Uint32 windowID; /**< The window that was dropped on, if any */ Uint32 windowID; /**< The window that was dropped on, if any */
} SDL_DropEvent; } SDL_DropEvent;
@@ -565,7 +565,7 @@ typedef struct SDL_DropEvent
typedef struct SDL_SensorEvent typedef struct SDL_SensorEvent
{ {
Uint32 type; /**< ::SDL_SENSORUPDATE */ Uint32 type; /**< ::SDL_SENSORUPDATE */
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
SDL_SensorID which; /**< The instance ID of the sensor */ SDL_SensorID which; /**< The instance ID of the sensor */
float data[6]; /**< Up to 6 values from the sensor - additional values can be queried using SDL_SensorGetData() */ float data[6]; /**< Up to 6 values from the sensor - additional values can be queried using SDL_SensorGetData() */
Uint64 timestamp_us; /**< The timestamp of the sensor reading in microseconds, if the hardware provides this information. */ Uint64 timestamp_us; /**< The timestamp of the sensor reading in microseconds, if the hardware provides this information. */
@@ -577,7 +577,7 @@ typedef struct SDL_SensorEvent
typedef struct SDL_QuitEvent typedef struct SDL_QuitEvent
{ {
Uint32 type; /**< ::SDL_QUIT */ Uint32 type; /**< ::SDL_QUIT */
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
} SDL_QuitEvent; } SDL_QuitEvent;
/** /**
@@ -586,7 +586,7 @@ typedef struct SDL_QuitEvent
typedef struct SDL_OSEvent typedef struct SDL_OSEvent
{ {
Uint32 type; /**< ::SDL_QUIT */ Uint32 type; /**< ::SDL_QUIT */
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
} SDL_OSEvent; } SDL_OSEvent;
/** /**
@@ -595,7 +595,7 @@ typedef struct SDL_OSEvent
typedef struct SDL_UserEvent typedef struct SDL_UserEvent
{ {
Uint32 type; /**< ::SDL_USEREVENT through ::SDL_LASTEVENT-1 */ Uint32 type; /**< ::SDL_USEREVENT through ::SDL_LASTEVENT-1 */
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
Uint32 windowID; /**< The associated window if any */ Uint32 windowID; /**< The associated window if any */
Sint32 code; /**< User defined event code */ Sint32 code; /**< User defined event code */
void *data1; /**< User defined data pointer */ void *data1; /**< User defined data pointer */
@@ -615,7 +615,7 @@ typedef struct SDL_SysWMmsg SDL_SysWMmsg;
typedef struct SDL_SysWMEvent typedef struct SDL_SysWMEvent
{ {
Uint32 type; /**< ::SDL_SYSWMEVENT */ Uint32 type; /**< ::SDL_SYSWMEVENT */
Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
SDL_SysWMmsg *msg; /**< driver dependent data, defined in SDL_syswm.h */ SDL_SysWMmsg *msg; /**< driver dependent data, defined in SDL_syswm.h */
} SDL_SysWMEvent; } SDL_SysWMEvent;
@@ -669,7 +669,7 @@ typedef union SDL_Event
the next multiple of 16, 64, and on architectures where pointers are the next multiple of 16, 64, and on architectures where pointers are
even larger the size of SDL_UserEvent will dominate as being 3 pointers. even larger the size of SDL_UserEvent will dominate as being 3 pointers.
*/ */
Uint8 padding[sizeof(void *) <= 8 ? 56 : sizeof(void *) == 16 ? 64 : 3 * sizeof(void *)]; Uint8 padding[128];
} SDL_Event; } SDL_Event;
/* Make sure we haven't broken binary compatibility */ /* Make sure we haven't broken binary compatibility */
@@ -879,6 +879,7 @@ extern DECLSPEC void SDLCALL SDL_FlushEvents(Uint32 minType, Uint32 maxType);
* \sa SDL_SetEventFilter * \sa SDL_SetEventFilter
* \sa SDL_WaitEvent * \sa SDL_WaitEvent
* \sa SDL_WaitEventTimeout * \sa SDL_WaitEventTimeout
* \sa SDL_WaitEventTimeoutNS
*/ */
extern DECLSPEC int SDLCALL SDL_PollEvent(SDL_Event * event); extern DECLSPEC int SDLCALL SDL_PollEvent(SDL_Event * event);
@@ -901,8 +902,9 @@ extern DECLSPEC int SDLCALL SDL_PollEvent(SDL_Event * event);
* \sa SDL_PollEvent * \sa SDL_PollEvent
* \sa SDL_PumpEvents * \sa SDL_PumpEvents
* \sa SDL_WaitEventTimeout * \sa SDL_WaitEventTimeout
* \sa SDL_WaitEventTimeoutNS
*/ */
extern DECLSPEC int SDLCALL SDL_WaitEvent(SDL_Event * event); extern DECLSPEC int SDLCALL SDL_WaitEvent(SDL_Event *event);
/** /**
* Wait until the specified timeout (in milliseconds) for the next available * Wait until the specified timeout (in milliseconds) for the next available
@@ -914,10 +916,13 @@ extern DECLSPEC int SDLCALL SDL_WaitEvent(SDL_Event * event);
* As this function may implicitly call SDL_PumpEvents(), you can only call * As this function may implicitly call SDL_PumpEvents(), you can only call
* this function in the thread that initialized the video subsystem. * this function in the thread that initialized the video subsystem.
* *
* The timeout is not guaranteed, the actual wait time could be longer
* due to system scheduling.
*
* \param event the SDL_Event structure to be filled in with the next event * \param event the SDL_Event structure to be filled in with the next event
* from the queue, or NULL * from the queue, or NULL
* \param timeout the maximum number of milliseconds to wait for the next * \param timeoutMS the maximum number of milliseconds to wait for the next
* available event * available event
* \returns 1 on success or 0 if there was an error while waiting for events; * \returns 1 on success or 0 if there was an error while waiting for events;
* call SDL_GetError() for more information. This also returns 0 if * call SDL_GetError() for more information. This also returns 0 if
* the timeout elapsed without an event arriving. * the timeout elapsed without an event arriving.
@@ -927,9 +932,39 @@ extern DECLSPEC int SDLCALL SDL_WaitEvent(SDL_Event * event);
* \sa SDL_PollEvent * \sa SDL_PollEvent
* \sa SDL_PumpEvents * \sa SDL_PumpEvents
* \sa SDL_WaitEvent * \sa SDL_WaitEvent
* \sa SDL_WaitEventTimeoutNS
*/ */
extern DECLSPEC int SDLCALL SDL_WaitEventTimeout(SDL_Event * event, extern DECLSPEC int SDLCALL SDL_WaitEventTimeout(SDL_Event *event, Sint32 timeoutMS);
int timeout);
/**
* Wait until the specified timeout (in nanoseconds) for the next available
* event.
*
* If `event` is not NULL, the next event is removed from the queue and stored
* in the SDL_Event structure pointed to by `event`.
*
* As this function may implicitly call SDL_PumpEvents(), you can only call
* this function in the thread that initialized the video subsystem.
*
* The timeout is not guaranteed, the actual wait time could be longer
* due to system scheduling.
*
* \param event the SDL_Event structure to be filled in with the next event
* from the queue, or NULL
* \param timeoutNS the maximum number of nanoseconds to wait for the next
* available event
* \returns 1 on success or 0 if there was an error while waiting for events;
* call SDL_GetError() for more information. This also returns 0 if
* the timeout elapsed without an event arriving.
*
* \since This function is available since SDL 3.0.0.
*
* \sa SDL_PollEvent
* \sa SDL_PumpEvents
* \sa SDL_WaitEvent
* \sa SDL_WaitEventTimeout
*/
extern DECLSPEC int SDLCALL SDL_WaitEventTimeoutNS(SDL_Event *event, Sint64 timeoutNS);
/** /**
* Add an event to the event queue. * Add an event to the event queue.
+82 -15
View File
@@ -46,7 +46,7 @@ extern "C" {
/** /**
* This is the timeout value which corresponds to never time out. * This is the timeout value which corresponds to never time out.
*/ */
#define SDL_MUTEX_MAXWAIT (~(Uint32)0) #define SDL_MUTEX_MAXWAIT -1
/** /**
@@ -194,6 +194,7 @@ typedef struct SDL_semaphore SDL_sem;
* \sa SDL_SemValue * \sa SDL_SemValue
* \sa SDL_SemWait * \sa SDL_SemWait
* \sa SDL_SemWaitTimeout * \sa SDL_SemWaitTimeout
* \sa SDL_SemWaitTimeoutNS
*/ */
extern DECLSPEC SDL_sem *SDLCALL SDL_CreateSemaphore(Uint32 initial_value); extern DECLSPEC SDL_sem *SDLCALL SDL_CreateSemaphore(Uint32 initial_value);
@@ -213,8 +214,9 @@ extern DECLSPEC SDL_sem *SDLCALL SDL_CreateSemaphore(Uint32 initial_value);
* \sa SDL_SemValue * \sa SDL_SemValue
* \sa SDL_SemWait * \sa SDL_SemWait
* \sa SDL_SemWaitTimeout * \sa SDL_SemWaitTimeout
* \sa SDL_SemWaitTimeoutNS
*/ */
extern DECLSPEC void SDLCALL SDL_DestroySemaphore(SDL_sem * sem); extern DECLSPEC void SDLCALL SDL_DestroySemaphore(SDL_sem *sem);
/** /**
* Wait until a semaphore has a positive value and then decrements it. * Wait until a semaphore has a positive value and then decrements it.
@@ -240,8 +242,9 @@ extern DECLSPEC void SDLCALL SDL_DestroySemaphore(SDL_sem * sem);
* \sa SDL_SemValue * \sa SDL_SemValue
* \sa SDL_SemWait * \sa SDL_SemWait
* \sa SDL_SemWaitTimeout * \sa SDL_SemWaitTimeout
* \sa SDL_SemWaitTimeoutNS
*/ */
extern DECLSPEC int SDLCALL SDL_SemWait(SDL_sem * sem); extern DECLSPEC int SDLCALL SDL_SemWait(SDL_sem *sem);
/** /**
* See if a semaphore has a positive value and decrement it if it does. * See if a semaphore has a positive value and decrement it if it does.
@@ -264,8 +267,9 @@ extern DECLSPEC int SDLCALL SDL_SemWait(SDL_sem * sem);
* \sa SDL_SemValue * \sa SDL_SemValue
* \sa SDL_SemWait * \sa SDL_SemWait
* \sa SDL_SemWaitTimeout * \sa SDL_SemWaitTimeout
* \sa SDL_SemWaitTimeoutNS
*/ */
extern DECLSPEC int SDLCALL SDL_SemTryWait(SDL_sem * sem); extern DECLSPEC int SDLCALL SDL_SemTryWait(SDL_sem *sem);
/** /**
* Wait until a semaphore has a positive value and then decrements it. * Wait until a semaphore has a positive value and then decrements it.
@@ -276,7 +280,7 @@ extern DECLSPEC int SDLCALL SDL_SemTryWait(SDL_sem * sem);
* successful it will atomically decrement the semaphore value. * successful it will atomically decrement the semaphore value.
* *
* \param sem the semaphore to wait on * \param sem the semaphore to wait on
* \param timeout the length of the timeout, in milliseconds * \param timeoutMS the length of the timeout, in milliseconds
* \returns 0 if the wait succeeds, `SDL_MUTEX_TIMEDOUT` if the wait does not * \returns 0 if the wait succeeds, `SDL_MUTEX_TIMEDOUT` if the wait does not
* succeed in the allotted time, or a negative error code on failure; * succeed in the allotted time, or a negative error code on failure;
* call SDL_GetError() for more information. * call SDL_GetError() for more information.
@@ -289,8 +293,35 @@ extern DECLSPEC int SDLCALL SDL_SemTryWait(SDL_sem * sem);
* \sa SDL_SemTryWait * \sa SDL_SemTryWait
* \sa SDL_SemValue * \sa SDL_SemValue
* \sa SDL_SemWait * \sa SDL_SemWait
* \sa SDL_SemWaitTimeoutNS
*/ */
extern DECLSPEC int SDLCALL SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout); extern DECLSPEC int SDLCALL SDL_SemWaitTimeout(SDL_sem *sem, Sint32 timeoutMS);
/**
* Wait until a semaphore has a positive value and then decrements it.
*
* This function suspends the calling thread until either the semaphore
* pointed to by `sem` has a positive value, the call is interrupted by a
* signal or error, or the specified time has elapsed. If the call is
* successful it will atomically decrement the semaphore value.
*
* \param sem the semaphore to wait on
* \param timeoutNS the length of the timeout, in nanoseconds
* \returns 0 if the wait succeeds, `SDL_MUTEX_TIMEDOUT` if the wait does not
* succeed in the allotted time, or a negative error code on failure;
* call SDL_GetError() for more information.
*
* \since This function is available since SDL 3.0.0.
*
* \sa SDL_CreateSemaphore
* \sa SDL_DestroySemaphore
* \sa SDL_SemPost
* \sa SDL_SemTryWait
* \sa SDL_SemValue
* \sa SDL_SemWait
* \sa SDL_SemWaitTimeout
*/
extern DECLSPEC int SDLCALL SDL_SemWaitTimeoutNS(SDL_sem *sem, Sint64 timeoutNS);
/** /**
* Atomically increment a semaphore's value and wake waiting threads. * Atomically increment a semaphore's value and wake waiting threads.
@@ -308,7 +339,7 @@ extern DECLSPEC int SDLCALL SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout);
* \sa SDL_SemWait * \sa SDL_SemWait
* \sa SDL_SemWaitTimeout * \sa SDL_SemWaitTimeout
*/ */
extern DECLSPEC int SDLCALL SDL_SemPost(SDL_sem * sem); extern DECLSPEC int SDLCALL SDL_SemPost(SDL_sem *sem);
/** /**
* Get the current value of a semaphore. * Get the current value of a semaphore.
@@ -320,7 +351,7 @@ extern DECLSPEC int SDLCALL SDL_SemPost(SDL_sem * sem);
* *
* \sa SDL_CreateSemaphore * \sa SDL_CreateSemaphore
*/ */
extern DECLSPEC Uint32 SDLCALL SDL_SemValue(SDL_sem * sem); extern DECLSPEC Uint32 SDLCALL SDL_SemValue(SDL_sem *sem);
/* @} *//* Semaphore functions */ /* @} *//* Semaphore functions */
@@ -346,6 +377,7 @@ typedef struct SDL_cond SDL_cond;
* \sa SDL_CondSignal * \sa SDL_CondSignal
* \sa SDL_CondWait * \sa SDL_CondWait
* \sa SDL_CondWaitTimeout * \sa SDL_CondWaitTimeout
* \sa SDL_CondWaitTimeoutNS
* \sa SDL_DestroyCond * \sa SDL_DestroyCond
*/ */
extern DECLSPEC SDL_cond *SDLCALL SDL_CreateCond(void); extern DECLSPEC SDL_cond *SDLCALL SDL_CreateCond(void);
@@ -361,9 +393,10 @@ extern DECLSPEC SDL_cond *SDLCALL SDL_CreateCond(void);
* \sa SDL_CondSignal * \sa SDL_CondSignal
* \sa SDL_CondWait * \sa SDL_CondWait
* \sa SDL_CondWaitTimeout * \sa SDL_CondWaitTimeout
* \sa SDL_CondWaitTimeoutNS
* \sa SDL_CreateCond * \sa SDL_CreateCond
*/ */
extern DECLSPEC void SDLCALL SDL_DestroyCond(SDL_cond * cond); extern DECLSPEC void SDLCALL SDL_DestroyCond(SDL_cond *cond);
/** /**
* Restart one of the threads that are waiting on the condition variable. * Restart one of the threads that are waiting on the condition variable.
@@ -377,10 +410,11 @@ extern DECLSPEC void SDLCALL SDL_DestroyCond(SDL_cond * cond);
* \sa SDL_CondBroadcast * \sa SDL_CondBroadcast
* \sa SDL_CondWait * \sa SDL_CondWait
* \sa SDL_CondWaitTimeout * \sa SDL_CondWaitTimeout
* \sa SDL_CondWaitTimeoutNS
* \sa SDL_CreateCond * \sa SDL_CreateCond
* \sa SDL_DestroyCond * \sa SDL_DestroyCond
*/ */
extern DECLSPEC int SDLCALL SDL_CondSignal(SDL_cond * cond); extern DECLSPEC int SDLCALL SDL_CondSignal(SDL_cond *cond);
/** /**
* Restart all threads that are waiting on the condition variable. * Restart all threads that are waiting on the condition variable.
@@ -394,10 +428,11 @@ extern DECLSPEC int SDLCALL SDL_CondSignal(SDL_cond * cond);
* \sa SDL_CondSignal * \sa SDL_CondSignal
* \sa SDL_CondWait * \sa SDL_CondWait
* \sa SDL_CondWaitTimeout * \sa SDL_CondWaitTimeout
* \sa SDL_CondWaitTimeoutNS
* \sa SDL_CreateCond * \sa SDL_CreateCond
* \sa SDL_DestroyCond * \sa SDL_DestroyCond
*/ */
extern DECLSPEC int SDLCALL SDL_CondBroadcast(SDL_cond * cond); extern DECLSPEC int SDLCALL SDL_CondBroadcast(SDL_cond *cond);
/** /**
* Wait until a condition variable is signaled. * Wait until a condition variable is signaled.
@@ -422,10 +457,11 @@ extern DECLSPEC int SDLCALL SDL_CondBroadcast(SDL_cond * cond);
* \sa SDL_CondBroadcast * \sa SDL_CondBroadcast
* \sa SDL_CondSignal * \sa SDL_CondSignal
* \sa SDL_CondWaitTimeout * \sa SDL_CondWaitTimeout
* \sa SDL_CondWaitTimeoutNS
* \sa SDL_CreateCond * \sa SDL_CreateCond
* \sa SDL_DestroyCond * \sa SDL_DestroyCond
*/ */
extern DECLSPEC int SDLCALL SDL_CondWait(SDL_cond * cond, SDL_mutex * mutex); extern DECLSPEC int SDLCALL SDL_CondWait(SDL_cond *cond, SDL_mutex *mutex);
/** /**
* Wait until a condition variable is signaled or a certain time has passed. * Wait until a condition variable is signaled or a certain time has passed.
@@ -440,7 +476,7 @@ extern DECLSPEC int SDLCALL SDL_CondWait(SDL_cond * cond, SDL_mutex * mutex);
* *
* \param cond the condition variable to wait on * \param cond the condition variable to wait on
* \param mutex the mutex used to coordinate thread access * \param mutex the mutex used to coordinate thread access
* \param ms the maximum time to wait, in milliseconds, or `SDL_MUTEX_MAXWAIT` * \param timeoutMS the maximum time to wait, in milliseconds, or `SDL_MUTEX_MAXWAIT`
* to wait indefinitely * to wait indefinitely
* \returns 0 if the condition variable is signaled, `SDL_MUTEX_TIMEDOUT` if * \returns 0 if the condition variable is signaled, `SDL_MUTEX_TIMEDOUT` if
* the condition is not signaled in the allotted time, or a negative * the condition is not signaled in the allotted time, or a negative
@@ -451,11 +487,42 @@ extern DECLSPEC int SDLCALL SDL_CondWait(SDL_cond * cond, SDL_mutex * mutex);
* \sa SDL_CondBroadcast * \sa SDL_CondBroadcast
* \sa SDL_CondSignal * \sa SDL_CondSignal
* \sa SDL_CondWait * \sa SDL_CondWait
* \sa SDL_CondWaitTimeoutNS
* \sa SDL_CreateCond * \sa SDL_CreateCond
* \sa SDL_DestroyCond * \sa SDL_DestroyCond
*/ */
extern DECLSPEC int SDLCALL SDL_CondWaitTimeout(SDL_cond * cond, extern DECLSPEC int SDLCALL SDL_CondWaitTimeout(SDL_cond *cond,
SDL_mutex * mutex, Uint32 ms); SDL_mutex *mutex, Sint32 timeoutMS);
/**
* Wait until a condition variable is signaled or a certain time has passed.
*
* This function unlocks the specified `mutex` and waits for another thread to
* call SDL_CondSignal() or SDL_CondBroadcast() on the condition variable
* `cond`, or for the specified time to elapse. Once the condition variable is
* signaled or the time elapsed, the mutex is re-locked and the function
* returns.
*
* The mutex must be locked before calling this function.
*
* \param cond the condition variable to wait on
* \param mutex the mutex used to coordinate thread access
* \param timeoutNS the maximum time to wait, in nanoseconds, or `SDL_MUTEX_MAXWAIT` to wait indefinitely
* \returns 0 if the condition variable is signaled, `SDL_MUTEX_TIMEDOUT` if
* the condition is not signaled in the allotted time, or a negative
* error code on failure; call SDL_GetError() for more information.
*
* \since This function is available since SDL 3.0.0.
*
* \sa SDL_CondBroadcast
* \sa SDL_CondSignal
* \sa SDL_CondWait
* \sa SDL_CondWaitTimeout
* \sa SDL_CreateCond
* \sa SDL_DestroyCond
*/
extern DECLSPEC int SDLCALL SDL_CondWaitTimeoutNS(SDL_cond *cond,
SDL_mutex *mutex, Sint64 timeoutNS);
/* @} *//* Condition variable functions */ /* @} *//* Condition variable functions */
+32 -54
View File
@@ -38,72 +38,37 @@ extern "C" {
#endif #endif
/** /**
* Get the number of milliseconds since SDL library initialization. * SDL time constants
*
* This value wraps if the program runs for more than ~49 days.
*
* This function is not recommended as of SDL 2.0.18; use SDL_GetTicks64()
* instead, where the value doesn't wrap every ~49 days. There are places in
* SDL where we provide a 32-bit timestamp that can not change without
* breaking binary compatibility, though, so this function isn't officially
* deprecated.
*
* \returns an unsigned 32-bit value representing the number of milliseconds
* since the SDL library initialized.
*
* \since This function is available since SDL 3.0.0.
*
* \sa SDL_TICKS_PASSED
*/ */
extern DECLSPEC Uint32 SDLCALL SDL_GetTicks(void); #define SDL_MS_PER_SECOND 1000
#define SDL_US_PER_SECOND 1000000
#define SDL_NS_PER_SECOND 1000000000LLU
#define SDL_NS_PER_MS 1000000
#define SDL_NS_PER_US 1000
#define SDL_MS_TO_NS(MS) (((Uint64)(MS)) * SDL_NS_PER_MS)
#define SDL_NS_TO_MS(NS) ((NS) / SDL_NS_PER_MS)
#define SDL_US_TO_NS(US) (((Uint64)(US)) * SDL_NS_PER_US)
#define SDL_NS_TO_US(NS) ((NS) / SDL_NS_PER_US)
/** /**
* Get the number of milliseconds since SDL library initialization. * Get the number of milliseconds since SDL library initialization.
* *
* Note that you should not use the SDL_TICKS_PASSED macro with values
* returned by this function, as that macro does clever math to compensate for
* the 32-bit overflow every ~49 days that SDL_GetTicks() suffers from. 64-bit
* values from this function can be safely compared directly.
*
* For example, if you want to wait 100 ms, you could do this:
*
* ```c
* const Uint64 timeout = SDL_GetTicks64() + 100;
* while (SDL_GetTicks64() < timeout) {
* // ... do work until timeout has elapsed
* }
* ```
*
* \returns an unsigned 64-bit value representing the number of milliseconds * \returns an unsigned 64-bit value representing the number of milliseconds
* since the SDL library initialized. * since the SDL library initialized.
* *
* \since This function is available since SDL 3.0.0. * \since This function is available since SDL 3.0.0.
*/ */
extern DECLSPEC Uint64 SDLCALL SDL_GetTicks64(void); extern DECLSPEC Uint64 SDLCALL SDL_GetTicks(void);
/** /**
* Compare 32-bit SDL ticks values, and return true if `A` has passed `B`. * Get the number of nanoseconds since SDL library initialization.
* *
* This should be used with results from SDL_GetTicks(), as this macro * \returns an unsigned 64-bit value representing the number of nanoseconds
* attempts to deal with the 32-bit counter wrapping back to zero every ~49 * since the SDL library initialized.
* days, but should _not_ be used with SDL_GetTicks64(), which does not have
* that problem.
* *
* For example, with SDL_GetTicks(), if you want to wait 100 ms, you could * \since This function is available since SDL 3.0.0.
* do this:
*
* ```c
* const Uint32 timeout = SDL_GetTicks() + 100;
* while (!SDL_TICKS_PASSED(SDL_GetTicks(), timeout)) {
* // ... do work until timeout has elapsed
* }
* ```
*
* Note that this does not handle tick differences greater
* than 2^31 so take care when using the above kind of code
* with large timeout delays (tens of days).
*/ */
#define SDL_TICKS_PASSED(A, B) ((Sint32)((B) - (A)) <= 0) extern DECLSPEC Uint64 SDLCALL SDL_GetTicksNS(void);
/** /**
* Get the current value of the high resolution counter. * Get the current value of the high resolution counter.
@@ -146,15 +111,28 @@ extern DECLSPEC Uint64 SDLCALL SDL_GetPerformanceFrequency(void);
*/ */
extern DECLSPEC void SDLCALL SDL_Delay(Uint32 ms); extern DECLSPEC void SDLCALL SDL_Delay(Uint32 ms);
/**
* Wait a specified number of nanoseconds before returning.
*
* This function waits a specified number of nanoseconds before returning. It
* waits at least the specified time, but possibly longer due to OS
* scheduling.
*
* \param ns the number of nanoseconds to delay
*
* \since This function is available since SDL 3.0.0.
*/
extern DECLSPEC void SDLCALL SDL_DelayNS(Uint64 ns);
/** /**
* Function prototype for the timer callback function. * Function prototype for the timer callback function.
* *
* The callback function is passed the current timer interval and returns * The callback function is passed the current timer interval and returns
* the next timer interval. If the returned value is the same as the one * the next timer interval, in milliseconds. If the returned value is the same as the one
* passed in, the periodic alarm continues, otherwise a new alarm is * passed in, the periodic alarm continues, otherwise a new alarm is
* scheduled. If the callback returns 0, the periodic alarm is cancelled. * scheduled. If the callback returns 0, the periodic alarm is cancelled.
*/ */
typedef Uint32 (SDLCALL * SDL_TimerCallback) (Uint32 interval, void *param); typedef Uint32 (SDLCALL *SDL_TimerCallback)(Uint32 interval, void *param);
/** /**
* Definition of the timer ID type. * Definition of the timer ID type.
@@ -179,7 +157,7 @@ typedef int SDL_TimerID;
* iteration. * iteration.
* *
* Timing may be inexact due to OS scheduling. Be sure to note the current * Timing may be inexact due to OS scheduling. Be sure to note the current
* time with SDL_GetTicks() or SDL_GetPerformanceCounter() in case your * time with SDL_GetTicksNS() or SDL_GetPerformanceCounter() in case your
* callback needs to adjust for variances. * callback needs to adjust for variances.
* *
* \param interval the timer delay, in milliseconds, passed to `callback` * \param interval the timer delay, in milliseconds, passed to `callback`
+2 -2
View File
@@ -909,8 +909,8 @@ static int SDLCALL ALSA_HotplugThread(void *arg)
while (!SDL_AtomicGet(&ALSA_hotplug_shutdown)) { while (!SDL_AtomicGet(&ALSA_hotplug_shutdown)) {
/* Block awhile before checking again, unless we're told to stop. */ /* Block awhile before checking again, unless we're told to stop. */
const Uint32 ticks = SDL_GetTicks() + 5000; const Uint64 ticks = SDL_GetTicks() + 5000;
while (!SDL_AtomicGet(&ALSA_hotplug_shutdown) && !SDL_TICKS_PASSED(SDL_GetTicks(), ticks)) { while (!SDL_AtomicGet(&ALSA_hotplug_shutdown) && SDL_GetTicks() < ticks) {
SDL_Delay(100); SDL_Delay(100);
} }
+13 -4
View File
@@ -32,7 +32,7 @@
#endif #endif
#include <errno.h> #include <errno.h>
int SDL_IOReady(int fd, int flags, int timeoutMS) int SDL_IOReady(int fd, int flags, Sint64 timeoutNS)
{ {
int result; int result;
@@ -42,6 +42,7 @@ int SDL_IOReady(int fd, int flags, int timeoutMS)
do { do {
#ifdef HAVE_POLL #ifdef HAVE_POLL
struct pollfd info; struct pollfd info;
int timeoutMS;
info.fd = fd; info.fd = fd;
info.events = 0; info.events = 0;
@@ -51,6 +52,14 @@ int SDL_IOReady(int fd, int flags, int timeoutMS)
if (flags & SDL_IOR_WRITE) { if (flags & SDL_IOR_WRITE) {
info.events |= POLLOUT; info.events |= POLLOUT;
} }
/* FIXME: Add support for ppoll() for nanosecond precision */
if (timeoutNS > 0) {
timeoutMS = (int)SDL_NS_TO_MS(timeoutNS);
} else if (timeoutNS == 0) {
timeoutMS = 0;
} else {
timeoutMS = -1;
}
result = poll(&info, 1, timeoutMS); result = poll(&info, 1, timeoutMS);
#else #else
fd_set rfdset, *rfdp = NULL; fd_set rfdset, *rfdp = NULL;
@@ -71,9 +80,9 @@ int SDL_IOReady(int fd, int flags, int timeoutMS)
wfdp = &wfdset; wfdp = &wfdset;
} }
if (timeoutMS >= 0) { if (timeoutNS >= 0) {
tv.tv_sec = timeoutMS / 1000; tv.tv_sec = (timeoutNS / SDL_NS_PER_SECOND);
tv.tv_usec = (timeoutMS % 1000) * 1000; tv.tv_usec = SDL_NS_TO_US(timeoutNS % SDL_NS_PER_SECOND);
tvp = &tv; tvp = &tv;
} }
+1 -1
View File
@@ -28,7 +28,7 @@
#define SDL_IOR_WRITE 0x2 #define SDL_IOR_WRITE 0x2
#define SDL_IOR_NO_RETRY 0x4 #define SDL_IOR_NO_RETRY 0x4
extern int SDL_IOReady(int fd, int flags, int timeoutMS); extern int SDL_IOReady(int fd, int flags, Sint64 timeoutNS);
#endif /* SDL_poll_h_ */ #endif /* SDL_poll_h_ */
+5 -1
View File
@@ -809,7 +809,6 @@
#define SDL_asprintf SDL_asprintf_REAL #define SDL_asprintf SDL_asprintf_REAL
#define SDL_vasprintf SDL_vasprintf_REAL #define SDL_vasprintf SDL_vasprintf_REAL
#define SDL_GetWindowICCProfile SDL_GetWindowICCProfile_REAL #define SDL_GetWindowICCProfile SDL_GetWindowICCProfile_REAL
#define SDL_GetTicks64 SDL_GetTicks64_REAL
#define SDL_LinuxSetThreadPriorityAndPolicy SDL_LinuxSetThreadPriorityAndPolicy_REAL #define SDL_LinuxSetThreadPriorityAndPolicy SDL_LinuxSetThreadPriorityAndPolicy_REAL
#define SDL_GameControllerGetAppleSFSymbolsNameForButton SDL_GameControllerGetAppleSFSymbolsNameForButton_REAL #define SDL_GameControllerGetAppleSFSymbolsNameForButton SDL_GameControllerGetAppleSFSymbolsNameForButton_REAL
#define SDL_GameControllerGetAppleSFSymbolsNameForAxis SDL_GameControllerGetAppleSFSymbolsNameForAxis_REAL #define SDL_GameControllerGetAppleSFSymbolsNameForAxis SDL_GameControllerGetAppleSFSymbolsNameForAxis_REAL
@@ -891,3 +890,8 @@
#define SDL_GDKSuspendComplete SDL_GDKSuspendComplete_REAL #define SDL_GDKSuspendComplete SDL_GDKSuspendComplete_REAL
#define SDL_GetWindowWMInfo SDL_GetWindowWMInfo_REAL #define SDL_GetWindowWMInfo SDL_GetWindowWMInfo_REAL
#define SDL_memset4 SDL_memset4_REAL #define SDL_memset4 SDL_memset4_REAL
#define SDL_WaitEventTimeoutNS SDL_WaitEventTimeoutNS_REAL
#define SDL_SemWaitTimeoutNS SDL_SemWaitTimeoutNS_REAL
#define SDL_CondWaitTimeoutNS SDL_CondWaitTimeoutNS_REAL
#define SDL_GetTicksNS SDL_GetTicksNS_REAL
#define SDL_DelayNS SDL_DelayNS_REAL
+9 -5
View File
@@ -147,7 +147,7 @@ SDL_DYNAPI_PROC(void,SDL_FlushEvent,(Uint32 a),(a),)
SDL_DYNAPI_PROC(void,SDL_FlushEvents,(Uint32 a, Uint32 b),(a,b),) SDL_DYNAPI_PROC(void,SDL_FlushEvents,(Uint32 a, Uint32 b),(a,b),)
SDL_DYNAPI_PROC(int,SDL_PollEvent,(SDL_Event *a),(a),return) SDL_DYNAPI_PROC(int,SDL_PollEvent,(SDL_Event *a),(a),return)
SDL_DYNAPI_PROC(int,SDL_WaitEvent,(SDL_Event *a),(a),return) SDL_DYNAPI_PROC(int,SDL_WaitEvent,(SDL_Event *a),(a),return)
SDL_DYNAPI_PROC(int,SDL_WaitEventTimeout,(SDL_Event *a, int b),(a,b),return) SDL_DYNAPI_PROC(int,SDL_WaitEventTimeout,(SDL_Event *a, Sint32 b),(a,b),return)
SDL_DYNAPI_PROC(int,SDL_PushEvent,(SDL_Event *a),(a),return) SDL_DYNAPI_PROC(int,SDL_PushEvent,(SDL_Event *a),(a),return)
SDL_DYNAPI_PROC(void,SDL_SetEventFilter,(SDL_EventFilter a, void *b),(a,b),) SDL_DYNAPI_PROC(void,SDL_SetEventFilter,(SDL_EventFilter a, void *b),(a,b),)
SDL_DYNAPI_PROC(SDL_bool,SDL_GetEventFilter,(SDL_EventFilter *a, void **b),(a,b),return) SDL_DYNAPI_PROC(SDL_bool,SDL_GetEventFilter,(SDL_EventFilter *a, void **b),(a,b),return)
@@ -291,7 +291,7 @@ SDL_DYNAPI_PROC(SDL_sem*,SDL_CreateSemaphore,(Uint32 a),(a),return)
SDL_DYNAPI_PROC(void,SDL_DestroySemaphore,(SDL_sem *a),(a),) SDL_DYNAPI_PROC(void,SDL_DestroySemaphore,(SDL_sem *a),(a),)
SDL_DYNAPI_PROC(int,SDL_SemWait,(SDL_sem *a),(a),return) SDL_DYNAPI_PROC(int,SDL_SemWait,(SDL_sem *a),(a),return)
SDL_DYNAPI_PROC(int,SDL_SemTryWait,(SDL_sem *a),(a),return) SDL_DYNAPI_PROC(int,SDL_SemTryWait,(SDL_sem *a),(a),return)
SDL_DYNAPI_PROC(int,SDL_SemWaitTimeout,(SDL_sem *a, Uint32 b),(a,b),return) SDL_DYNAPI_PROC(int,SDL_SemWaitTimeout,(SDL_sem *a, Sint32 b),(a,b),return)
SDL_DYNAPI_PROC(int,SDL_SemPost,(SDL_sem *a),(a),return) SDL_DYNAPI_PROC(int,SDL_SemPost,(SDL_sem *a),(a),return)
SDL_DYNAPI_PROC(Uint32,SDL_SemValue,(SDL_sem *a),(a),return) SDL_DYNAPI_PROC(Uint32,SDL_SemValue,(SDL_sem *a),(a),return)
SDL_DYNAPI_PROC(SDL_cond*,SDL_CreateCond,(void),(),return) SDL_DYNAPI_PROC(SDL_cond*,SDL_CreateCond,(void),(),return)
@@ -299,7 +299,7 @@ SDL_DYNAPI_PROC(void,SDL_DestroyCond,(SDL_cond *a),(a),)
SDL_DYNAPI_PROC(int,SDL_CondSignal,(SDL_cond *a),(a),return) SDL_DYNAPI_PROC(int,SDL_CondSignal,(SDL_cond *a),(a),return)
SDL_DYNAPI_PROC(int,SDL_CondBroadcast,(SDL_cond *a),(a),return) SDL_DYNAPI_PROC(int,SDL_CondBroadcast,(SDL_cond *a),(a),return)
SDL_DYNAPI_PROC(int,SDL_CondWait,(SDL_cond *a, SDL_mutex *b),(a,b),return) SDL_DYNAPI_PROC(int,SDL_CondWait,(SDL_cond *a, SDL_mutex *b),(a,b),return)
SDL_DYNAPI_PROC(int,SDL_CondWaitTimeout,(SDL_cond *a, SDL_mutex *b, Uint32 c),(a,b,c),return) SDL_DYNAPI_PROC(int,SDL_CondWaitTimeout,(SDL_cond *a, SDL_mutex *b, Sint32 c),(a,b,c),return)
SDL_DYNAPI_PROC(const char*,SDL_GetPixelFormatName,(Uint32 a),(a),return) SDL_DYNAPI_PROC(const char*,SDL_GetPixelFormatName,(Uint32 a),(a),return)
SDL_DYNAPI_PROC(SDL_bool,SDL_PixelFormatEnumToMasks,(Uint32 a, int *b, Uint32 *c, Uint32 *d, Uint32 *e, Uint32 *f),(a,b,c,d,e,f),return) SDL_DYNAPI_PROC(SDL_bool,SDL_PixelFormatEnumToMasks,(Uint32 a, int *b, Uint32 *c, Uint32 *d, Uint32 *e, Uint32 *f),(a,b,c,d,e,f),return)
SDL_DYNAPI_PROC(Uint32,SDL_MasksToPixelFormatEnum,(int a, Uint32 b, Uint32 c, Uint32 d, Uint32 e),(a,b,c,d,e),return) SDL_DYNAPI_PROC(Uint32,SDL_MasksToPixelFormatEnum,(int a, Uint32 b, Uint32 c, Uint32 d, Uint32 e),(a,b,c,d,e),return)
@@ -500,7 +500,7 @@ SDL_DYNAPI_PROC(void,SDL_DetachThread,(SDL_Thread *a),(a),)
SDL_DYNAPI_PROC(SDL_TLSID,SDL_TLSCreate,(void),(),return) SDL_DYNAPI_PROC(SDL_TLSID,SDL_TLSCreate,(void),(),return)
SDL_DYNAPI_PROC(void*,SDL_TLSGet,(SDL_TLSID a),(a),return) SDL_DYNAPI_PROC(void*,SDL_TLSGet,(SDL_TLSID a),(a),return)
SDL_DYNAPI_PROC(int,SDL_TLSSet,(SDL_TLSID a, const void *b, void (SDLCALL *c)(void*)),(a,b,c),return) SDL_DYNAPI_PROC(int,SDL_TLSSet,(SDL_TLSID a, const void *b, void (SDLCALL *c)(void*)),(a,b,c),return)
SDL_DYNAPI_PROC(Uint32,SDL_GetTicks,(void),(),return) SDL_DYNAPI_PROC(Uint64,SDL_GetTicks,(void),(),return)
SDL_DYNAPI_PROC(Uint64,SDL_GetPerformanceCounter,(void),(),return) SDL_DYNAPI_PROC(Uint64,SDL_GetPerformanceCounter,(void),(),return)
SDL_DYNAPI_PROC(Uint64,SDL_GetPerformanceFrequency,(void),(),return) SDL_DYNAPI_PROC(Uint64,SDL_GetPerformanceFrequency,(void),(),return)
SDL_DYNAPI_PROC(void,SDL_Delay,(Uint32 a),(a),) SDL_DYNAPI_PROC(void,SDL_Delay,(Uint32 a),(a),)
@@ -874,7 +874,6 @@ SDL_DYNAPI_PROC(int,SDL_asprintf,(char **a, SDL_PRINTF_FORMAT_STRING const char
#endif #endif
SDL_DYNAPI_PROC(int,SDL_vasprintf,(char **a, const char *b, va_list c),(a,b,c),return) SDL_DYNAPI_PROC(int,SDL_vasprintf,(char **a, const char *b, va_list c),(a,b,c),return)
SDL_DYNAPI_PROC(void*,SDL_GetWindowICCProfile,(SDL_Window *a, size_t *b),(a,b),return) SDL_DYNAPI_PROC(void*,SDL_GetWindowICCProfile,(SDL_Window *a, size_t *b),(a,b),return)
SDL_DYNAPI_PROC(Uint64,SDL_GetTicks64,(void),(),return)
#ifdef __LINUX__ #ifdef __LINUX__
SDL_DYNAPI_PROC(int,SDL_LinuxSetThreadPriorityAndPolicy,(Sint64 a, int b, int c),(a,b,c),return) SDL_DYNAPI_PROC(int,SDL_LinuxSetThreadPriorityAndPolicy,(Sint64 a, int b, int c),(a,b,c),return)
#endif #endif
@@ -967,3 +966,8 @@ SDL_DYNAPI_PROC(void,SDL_GDKSuspendComplete,(void),(),)
#endif #endif
SDL_DYNAPI_PROC(int,SDL_GetWindowWMInfo,(SDL_Window *a, SDL_SysWMinfo *b, Uint32 c),(a,b,c),return) SDL_DYNAPI_PROC(int,SDL_GetWindowWMInfo,(SDL_Window *a, SDL_SysWMinfo *b, Uint32 c),(a,b,c),return)
SDL_DYNAPI_PROC(void*,SDL_memset4,(void *a, Uint32 b, size_t c),(a,b,c),return) SDL_DYNAPI_PROC(void*,SDL_memset4,(void *a, Uint32 b, size_t c),(a,b,c),return)
SDL_DYNAPI_PROC(int,SDL_WaitEventTimeoutNS,(SDL_Event *a, Sint64 b),(a,b),return)
SDL_DYNAPI_PROC(int,SDL_SemWaitTimeoutNS,(SDL_sem *a, Sint64 b),(a,b),return)
SDL_DYNAPI_PROC(int,SDL_CondWaitTimeoutNS,(SDL_cond *a, SDL_mutex *b, Sint64 c),(a,b,c),return)
SDL_DYNAPI_PROC(Uint64,SDL_GetTicksNS,(void),(),return)
SDL_DYNAPI_PROC(void,SDL_DelayNS,(Uint64 a),(a),)
+38 -26
View File
@@ -42,7 +42,7 @@
#define SDL_MAX_QUEUED_EVENTS 65535 #define SDL_MAX_QUEUED_EVENTS 65535
/* Determines how often we wake to call SDL_PumpEvents() in SDL_WaitEventTimeout_Device() */ /* Determines how often we wake to call SDL_PumpEvents() in SDL_WaitEventTimeout_Device() */
#define PERIODIC_POLL_INTERVAL_MS 3000 #define PERIODIC_POLL_INTERVAL_NS (3 * SDL_NS_PER_SECOND)
typedef struct SDL_EventWatcher typedef struct SDL_EventWatcher
{ {
@@ -963,7 +963,7 @@ void SDL_PumpEvents()
int SDL_PollEvent(SDL_Event *event) int SDL_PollEvent(SDL_Event *event)
{ {
return SDL_WaitEventTimeout(event, 0); return SDL_WaitEventTimeoutNS(event, 0);
} }
static SDL_bool SDL_events_need_periodic_poll() static SDL_bool SDL_events_need_periodic_poll()
@@ -983,9 +983,9 @@ static SDL_bool SDL_events_need_periodic_poll()
return need_periodic_poll; return need_periodic_poll;
} }
static int SDL_WaitEventTimeout_Device(_THIS, SDL_Window *wakeup_window, SDL_Event *event, Uint32 start, int timeout) static int SDL_WaitEventTimeout_Device(_THIS, SDL_Window *wakeup_window, SDL_Event *event, Uint64 start, Sint64 timeoutNS)
{ {
int loop_timeout = timeout; Sint64 loop_timeoutNS = timeoutNS;
SDL_bool need_periodic_poll = SDL_events_need_periodic_poll(); SDL_bool need_periodic_poll = SDL_events_need_periodic_poll();
for (;;) { for (;;) {
@@ -1021,26 +1021,26 @@ static int SDL_WaitEventTimeout_Device(_THIS, SDL_Window *wakeup_window, SDL_Eve
return 1; return 1;
} }
/* No events found in the queue, call WaitEventTimeout to wait for an event. */ /* No events found in the queue, call WaitEventTimeout to wait for an event. */
if (timeout > 0) { if (timeoutNS > 0) {
Uint32 elapsed = SDL_GetTicks() - start; Sint64 elapsed = SDL_GetTicksNS() - start;
if (elapsed >= (Uint32)timeout) { if (elapsed >= timeoutNS) {
/* Set wakeup_window to NULL without holding the lock. */ /* Set wakeup_window to NULL without holding the lock. */
_this->wakeup_window = NULL; _this->wakeup_window = NULL;
return 0; return 0;
} }
loop_timeout = (int)((Uint32)timeout - elapsed); loop_timeoutNS = (timeoutNS - elapsed);
} }
if (need_periodic_poll) { if (need_periodic_poll) {
if (loop_timeout >= 0) { if (loop_timeoutNS >= 0) {
loop_timeout = SDL_min(loop_timeout, PERIODIC_POLL_INTERVAL_MS); loop_timeoutNS = SDL_min(loop_timeoutNS, PERIODIC_POLL_INTERVAL_NS);
} else { } else {
loop_timeout = PERIODIC_POLL_INTERVAL_MS; loop_timeoutNS = PERIODIC_POLL_INTERVAL_NS;
} }
} }
status = _this->WaitEventTimeout(_this, loop_timeout); status = _this->WaitEventTimeout(_this, loop_timeoutNS);
/* Set wakeup_window to NULL without holding the lock. */ /* Set wakeup_window to NULL without holding the lock. */
_this->wakeup_window = NULL; _this->wakeup_window = NULL;
if (status == 0 && need_periodic_poll && loop_timeout == PERIODIC_POLL_INTERVAL_MS) { if (status == 0 && need_periodic_poll && loop_timeoutNS == PERIODIC_POLL_INTERVAL_NS) {
/* We may have woken up to poll. Try again */ /* We may have woken up to poll. Try again */
continue; continue;
} else if (status <= 0) { } else if (status <= 0) {
@@ -1086,15 +1086,27 @@ static SDL_Window *SDL_find_active_window(SDL_VideoDevice *_this)
int SDL_WaitEvent(SDL_Event *event) int SDL_WaitEvent(SDL_Event *event)
{ {
return SDL_WaitEventTimeout(event, -1); return SDL_WaitEventTimeoutNS(event, -1);
} }
int SDL_WaitEventTimeout(SDL_Event *event, int timeout) int SDL_WaitEventTimeout(SDL_Event *event, Sint32 timeoutMS)
{
Uint64 timeoutNS;
if (timeoutMS > 0) {
timeoutNS = SDL_MS_TO_NS(timeoutMS);
} else {
timeoutNS = timeoutMS;
}
return SDL_WaitEventTimeoutNS(event, timeoutNS);
}
int SDL_WaitEventTimeoutNS(SDL_Event *event, Sint64 timeoutNS)
{ {
SDL_VideoDevice *_this = SDL_GetVideoDevice(); SDL_VideoDevice *_this = SDL_GetVideoDevice();
SDL_Window *wakeup_window; SDL_Window *wakeup_window;
Uint32 start, expiration; Uint64 start, expiration;
SDL_bool include_sentinel = (timeout == 0) ? SDL_TRUE : SDL_FALSE; SDL_bool include_sentinel = (timeoutNS == 0) ? SDL_TRUE : SDL_FALSE;
int result; int result;
/* If there isn't a poll sentinel event pending, pump events and add one */ /* If there isn't a poll sentinel event pending, pump events and add one */
@@ -1126,7 +1138,7 @@ int SDL_WaitEventTimeout(SDL_Event *event, int timeout)
} }
} }
if (result == 0) { if (result == 0) {
if (timeout == 0) { if (timeoutNS == 0) {
/* No events available, and not willing to wait */ /* No events available, and not willing to wait */
return 0; return 0;
} }
@@ -1134,12 +1146,12 @@ int SDL_WaitEventTimeout(SDL_Event *event, int timeout)
/* Has existing events */ /* Has existing events */
return 1; return 1;
} }
/* We should have completely handled timeout == 0 above */ /* We should have completely handled timeoutNS == 0 above */
SDL_assert(timeout != 0); SDL_assert(timeoutNS != 0);
if (timeout > 0) { if (timeoutNS > 0) {
start = SDL_GetTicks(); start = SDL_GetTicksNS();
expiration = start + timeout; expiration = start + timeoutNS;
} else { } else {
start = 0; start = 0;
expiration = 0; expiration = 0;
@@ -1149,7 +1161,7 @@ int SDL_WaitEventTimeout(SDL_Event *event, int timeout)
/* Look if a shown window is available to send the wakeup event. */ /* Look if a shown window is available to send the wakeup event. */
wakeup_window = SDL_find_active_window(_this); wakeup_window = SDL_find_active_window(_this);
if (wakeup_window) { if (wakeup_window) {
int status = SDL_WaitEventTimeout_Device(_this, wakeup_window, event, start, timeout); int status = SDL_WaitEventTimeout_Device(_this, wakeup_window, event, start, timeoutNS);
/* There may be implementation-defined conditions where the backend cannot /* There may be implementation-defined conditions where the backend cannot
reliably wait for the next event. If that happens, fall back to polling. */ reliably wait for the next event. If that happens, fall back to polling. */
@@ -1165,7 +1177,7 @@ int SDL_WaitEventTimeout(SDL_Event *event, int timeout)
case -1: case -1:
return 0; return 0;
case 0: case 0:
if (timeout > 0 && SDL_TICKS_PASSED(SDL_GetTicks(), expiration)) { if (timeoutNS > 0 && SDL_GetTicks() >= expiration) {
/* Timeout expired and no events */ /* Timeout expired and no events */
return 0; return 0;
} }
@@ -1180,7 +1192,7 @@ int SDL_WaitEventTimeout(SDL_Event *event, int timeout)
int SDL_PushEvent(SDL_Event *event) int SDL_PushEvent(SDL_Event *event)
{ {
event->common.timestamp = SDL_GetTicks(); event->common.timestamp = SDL_GetTicksNS();
if (SDL_EventOK.callback || SDL_event_watchers_count > 0) { if (SDL_EventOK.callback || SDL_event_watchers_count > 0) {
if (SDL_event_watchers_lock == NULL || SDL_LockMutex(SDL_event_watchers_lock) == 0) { if (SDL_event_watchers_lock == NULL || SDL_LockMutex(SDL_event_watchers_lock) == 0) {
+2 -2
View File
@@ -735,9 +735,9 @@ static int SDL_PrivateSendMouseButton(SDL_Window *window, SDL_MouseID mouseID, U
SDL_MouseClickState *clickstate = GetMouseClickState(mouse, button); SDL_MouseClickState *clickstate = GetMouseClickState(mouse, button);
if (clickstate) { if (clickstate) {
if (state == SDL_PRESSED) { if (state == SDL_PRESSED) {
Uint32 now = SDL_GetTicks(); Uint64 now = SDL_GetTicks();
if (SDL_TICKS_PASSED(now, clickstate->last_timestamp + mouse->double_click_time) || if (now >= (clickstate->last_timestamp + mouse->double_click_time) ||
SDL_abs(mouse->x - clickstate->last_x) > mouse->double_click_radius || SDL_abs(mouse->x - clickstate->last_x) > mouse->double_click_radius ||
SDL_abs(mouse->y - clickstate->last_y) > mouse->double_click_radius) { SDL_abs(mouse->y - clickstate->last_y) > mouse->double_click_radius) {
clickstate->click_count = 0; clickstate->click_count = 0;
+1 -1
View File
@@ -38,7 +38,7 @@ typedef struct
typedef struct typedef struct
{ {
int last_x, last_y; int last_x, last_y;
Uint32 last_timestamp; Uint64 last_timestamp;
Uint8 click_count; Uint8 click_count;
} SDL_MouseClickState; } SDL_MouseClickState;
+2 -9
View File
@@ -42,15 +42,8 @@ static int numhaptics = 0;
int SDL_SYS_HapticInit(void) int SDL_SYS_HapticInit(void)
{ {
/* Support for device connect/disconnect is API >= 16 only, Android_JNI_PollHapticDevices();
* so we poll every three seconds
* Ref: http://developer.android.com/reference/android/hardware/input/InputManager.InputDeviceListener.html
*/
static Uint32 timeout = 0;
if (SDL_TICKS_PASSED(SDL_GetTicks(), timeout)) {
timeout = SDL_GetTicks() + 3000;
Android_JNI_PollHapticDevices();
}
return numhaptics; return numhaptics;
} }
+1 -1
View File
@@ -46,7 +46,7 @@ struct haptic_hwdata
Uint8 userid; /* XInput userid index for this joystick */ Uint8 userid; /* XInput userid index for this joystick */
SDL_Thread *thread; SDL_Thread *thread;
SDL_mutex *mutex; SDL_mutex *mutex;
Uint32 stopTicks; Uint64 stopTicks;
SDL_atomic_t stopThread; SDL_atomic_t stopThread;
}; };
+1 -4
View File
@@ -147,7 +147,7 @@ static int SDLCALL SDL_RunXInputHaptic(void *arg)
SDL_LockMutex(hwdata->mutex); SDL_LockMutex(hwdata->mutex);
/* If we're currently running and need to stop... */ /* If we're currently running and need to stop... */
if (hwdata->stopTicks) { if (hwdata->stopTicks) {
if ((hwdata->stopTicks != SDL_HAPTIC_INFINITY) && SDL_TICKS_PASSED(SDL_GetTicks(), hwdata->stopTicks)) { if ((hwdata->stopTicks != SDL_HAPTIC_INFINITY) && SDL_GetTicks() >= hwdata->stopTicks) {
XINPUT_VIBRATION vibration = { 0, 0 }; XINPUT_VIBRATION vibration = { 0, 0 };
hwdata->stopTicks = 0; hwdata->stopTicks = 0;
XINPUTSETSTATE(hwdata->userid, &vibration); XINPUTSETSTATE(hwdata->userid, &vibration);
@@ -287,9 +287,6 @@ int SDL_XINPUT_HapticRunEffect(SDL_Haptic *haptic, struct haptic_effect *effect,
/* do nothing. Effect runs for zero milliseconds. */ /* do nothing. Effect runs for zero milliseconds. */
} else { } else {
haptic->hwdata->stopTicks = SDL_GetTicks() + (effect->effect.leftright.length * iterations); haptic->hwdata->stopTicks = SDL_GetTicks() + (effect->effect.leftright.length * iterations);
if ((haptic->hwdata->stopTicks == SDL_HAPTIC_INFINITY) || (haptic->hwdata->stopTicks == 0)) {
haptic->hwdata->stopTicks = 1; /* fix edge cases. */
}
} }
SDL_UnlockMutex(haptic->hwdata->mutex); SDL_UnlockMutex(haptic->hwdata->mutex);
return (XINPUTSETSTATE(haptic->hwdata->userid, vib) == ERROR_SUCCESS) ? 0 : -1; return (XINPUTSETSTATE(haptic->hwdata->userid, vib) == ERROR_SUCCESS) ? 0 : -1;
+3 -3
View File
@@ -92,7 +92,7 @@ static struct
SDL_bool m_bInitialized; SDL_bool m_bInitialized;
Uint32 m_unDeviceChangeCounter; Uint32 m_unDeviceChangeCounter;
SDL_bool m_bCanGetNotifications; SDL_bool m_bCanGetNotifications;
Uint32 m_unLastDetect; Uint64 m_unLastDetect;
#if defined(__WIN32__) || defined(__WINGDK__) #if defined(__WIN32__) || defined(__WINGDK__)
SDL_threadID m_nThreadID; SDL_threadID m_nThreadID;
@@ -367,8 +367,8 @@ HIDAPI_UpdateDiscovery()
if (!SDL_HIDAPI_discovery.m_bCanGetNotifications) { if (!SDL_HIDAPI_discovery.m_bCanGetNotifications) {
const Uint32 SDL_HIDAPI_DETECT_INTERVAL_MS = 3000; /* Update every 3 seconds */ const Uint32 SDL_HIDAPI_DETECT_INTERVAL_MS = 3000; /* Update every 3 seconds */
Uint32 now = SDL_GetTicks(); Uint64 now = SDL_GetTicks();
if (!SDL_HIDAPI_discovery.m_unLastDetect || SDL_TICKS_PASSED(now, SDL_HIDAPI_discovery.m_unLastDetect + SDL_HIDAPI_DETECT_INTERVAL_MS)) { if (!SDL_HIDAPI_discovery.m_unLastDetect || now >= (SDL_HIDAPI_discovery.m_unLastDetect + SDL_HIDAPI_DETECT_INTERVAL_MS)) {
++SDL_HIDAPI_discovery.m_unDeviceChangeCounter; ++SDL_HIDAPI_discovery.m_unDeviceChangeCounter;
SDL_HIDAPI_discovery.m_unLastDetect = now; SDL_HIDAPI_discovery.m_unLastDetect = now;
} }
+3 -3
View File
@@ -128,7 +128,7 @@ struct _SDL_GameController
SDL_ExtendedGameControllerBind *bindings; SDL_ExtendedGameControllerBind *bindings;
SDL_ExtendedGameControllerBind **last_match_axis; SDL_ExtendedGameControllerBind **last_match_axis;
Uint8 *last_hat_mask; Uint8 *last_hat_mask;
Uint32 guide_button_down; Uint64 guide_button_down;
struct _SDL_GameController *next; /* pointer to next game controller we have allocated */ struct _SDL_GameController *next; /* pointer to next game controller we have allocated */
}; };
@@ -2901,7 +2901,7 @@ static int SDL_PrivateGameControllerButton(SDL_GameController *gamecontroller, S
#endif /* !SDL_EVENTS_DISABLED */ #endif /* !SDL_EVENTS_DISABLED */
if (button == SDL_CONTROLLER_BUTTON_GUIDE) { if (button == SDL_CONTROLLER_BUTTON_GUIDE) {
Uint32 now = SDL_GetTicks(); Uint64 now = SDL_GetTicks();
if (state == SDL_PRESSED) { if (state == SDL_PRESSED) {
gamecontroller->guide_button_down = now; gamecontroller->guide_button_down = now;
@@ -2910,7 +2910,7 @@ static int SDL_PrivateGameControllerButton(SDL_GameController *gamecontroller, S
return 0; return 0;
} }
} else { } else {
if (!SDL_TICKS_PASSED(now, gamecontroller->guide_button_down + SDL_MINIMUM_GUIDE_BUTTON_DELAY_MS)) { if (now < (gamecontroller->guide_button_down + SDL_MINIMUM_GUIDE_BUTTON_DELAY_MS)) {
gamecontroller->joystick->delayed_guide_button = SDL_TRUE; gamecontroller->joystick->delayed_guide_button = SDL_TRUE;
return 0; return 0;
} }
+5 -17
View File
@@ -966,9 +966,6 @@ int SDL_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint
} else { } else {
result = joystick->driver->Rumble(joystick, low_frequency_rumble, high_frequency_rumble); result = joystick->driver->Rumble(joystick, low_frequency_rumble, high_frequency_rumble);
joystick->rumble_resend = SDL_GetTicks() + SDL_RUMBLE_RESEND_MS; joystick->rumble_resend = SDL_GetTicks() + SDL_RUMBLE_RESEND_MS;
if (!joystick->rumble_resend) {
joystick->rumble_resend = 1;
}
} }
if (result == 0) { if (result == 0) {
@@ -977,9 +974,6 @@ int SDL_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint
if ((low_frequency_rumble || high_frequency_rumble) && duration_ms) { if ((low_frequency_rumble || high_frequency_rumble) && duration_ms) {
joystick->rumble_expiration = SDL_GetTicks() + SDL_min(duration_ms, SDL_MAX_RUMBLE_DURATION_MS); joystick->rumble_expiration = SDL_GetTicks() + SDL_min(duration_ms, SDL_MAX_RUMBLE_DURATION_MS);
if (!joystick->rumble_expiration) {
joystick->rumble_expiration = 1;
}
} else { } else {
joystick->rumble_expiration = 0; joystick->rumble_expiration = 0;
joystick->rumble_resend = 0; joystick->rumble_resend = 0;
@@ -1010,9 +1004,6 @@ int SDL_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint1
if ((left_rumble || right_rumble) && duration_ms) { if ((left_rumble || right_rumble) && duration_ms) {
joystick->trigger_rumble_expiration = SDL_GetTicks() + SDL_min(duration_ms, SDL_MAX_RUMBLE_DURATION_MS); joystick->trigger_rumble_expiration = SDL_GetTicks() + SDL_min(duration_ms, SDL_MAX_RUMBLE_DURATION_MS);
if (!joystick->trigger_rumble_expiration) {
joystick->trigger_rumble_expiration = 1;
}
} else { } else {
joystick->trigger_rumble_expiration = 0; joystick->trigger_rumble_expiration = 0;
} }
@@ -1083,7 +1074,7 @@ int SDL_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blu
green != joystick->led_green || green != joystick->led_green ||
blue != joystick->led_blue; blue != joystick->led_blue;
if (isfreshvalue || SDL_TICKS_PASSED(SDL_GetTicks(), joystick->led_expiration)) { if (isfreshvalue || SDL_GetTicks() >= joystick->led_expiration) {
result = joystick->driver->SetLED(joystick, red, green, blue); result = joystick->driver->SetLED(joystick, red, green, blue);
joystick->led_expiration = SDL_GetTicks() + SDL_LED_MIN_REPEAT_MS; joystick->led_expiration = SDL_GetTicks() + SDL_LED_MIN_REPEAT_MS;
} else { } else {
@@ -1665,7 +1656,7 @@ int SDL_PrivateJoystickButton(SDL_Joystick *joystick, Uint8 button, Uint8 state)
void SDL_JoystickUpdate(void) void SDL_JoystickUpdate(void)
{ {
int i; int i;
Uint32 now; Uint64 now;
SDL_Joystick *joystick; SDL_Joystick *joystick;
if (!SDL_WasInit(SDL_INIT_JOYSTICK)) { if (!SDL_WasInit(SDL_INIT_JOYSTICK)) {
@@ -1689,14 +1680,12 @@ void SDL_JoystickUpdate(void)
} }
now = SDL_GetTicks(); now = SDL_GetTicks();
if (joystick->rumble_expiration && if (joystick->rumble_expiration && now >= joystick->rumble_expiration) {
SDL_TICKS_PASSED(now, joystick->rumble_expiration)) {
SDL_JoystickRumble(joystick, 0, 0, 0); SDL_JoystickRumble(joystick, 0, 0, 0);
joystick->rumble_resend = 0; joystick->rumble_resend = 0;
} }
if (joystick->rumble_resend && if (joystick->rumble_resend && now >= joystick->rumble_resend) {
SDL_TICKS_PASSED(now, joystick->rumble_resend)) {
joystick->driver->Rumble(joystick, joystick->low_frequency_rumble, joystick->high_frequency_rumble); joystick->driver->Rumble(joystick, joystick->low_frequency_rumble, joystick->high_frequency_rumble);
joystick->rumble_resend = now + SDL_RUMBLE_RESEND_MS; joystick->rumble_resend = now + SDL_RUMBLE_RESEND_MS;
if (joystick->rumble_resend == 0) { if (joystick->rumble_resend == 0) {
@@ -1704,8 +1693,7 @@ void SDL_JoystickUpdate(void)
} }
} }
if (joystick->trigger_rumble_expiration && if (joystick->trigger_rumble_expiration && now >= joystick->trigger_rumble_expiration) {
SDL_TICKS_PASSED(now, joystick->trigger_rumble_expiration)) {
SDL_JoystickRumbleTriggers(joystick, 0, 0, 0); SDL_JoystickRumbleTriggers(joystick, 0, 0, 0);
} }
} }
+4 -4
View File
@@ -102,17 +102,17 @@ struct _SDL_Joystick
Uint16 low_frequency_rumble; Uint16 low_frequency_rumble;
Uint16 high_frequency_rumble; Uint16 high_frequency_rumble;
Uint32 rumble_expiration; Uint64 rumble_expiration;
Uint32 rumble_resend; Uint64 rumble_resend;
Uint16 left_trigger_rumble; Uint16 left_trigger_rumble;
Uint16 right_trigger_rumble; Uint16 right_trigger_rumble;
Uint32 trigger_rumble_expiration; Uint64 trigger_rumble_expiration;
Uint8 led_red; Uint8 led_red;
Uint8 led_green; Uint8 led_green;
Uint8 led_blue; Uint8 led_blue;
Uint32 led_expiration; Uint64 led_expiration;
SDL_bool attached; SDL_bool attached;
SDL_bool is_game_controller; SDL_bool is_game_controller;
+4 -3
View File
@@ -494,9 +494,10 @@ static void ANDROID_JoystickDetect(void)
* so we poll every three seconds * so we poll every three seconds
* Ref: http://developer.android.com/reference/android/hardware/input/InputManager.InputDeviceListener.html * Ref: http://developer.android.com/reference/android/hardware/input/InputManager.InputDeviceListener.html
*/ */
static Uint32 timeout = 0; static Uint64 timeout = 0;
if (!timeout || SDL_TICKS_PASSED(SDL_GetTicks(), timeout)) { Uint64 now = SDL_GetTicks();
timeout = SDL_GetTicks() + 3000; if (!timeout || now >= timeout) {
timeout = now + 3000;
Android_JNI_PollInputDevices(); Android_JNI_PollInputDevices();
} }
} }
+4 -4
View File
@@ -137,7 +137,7 @@ typedef struct
SDL_bool report_touchpad; SDL_bool report_touchpad;
SDL_bool hardware_calibration; SDL_bool hardware_calibration;
IMUCalibrationData calibration[6]; IMUCalibrationData calibration[6];
Uint32 last_packet; Uint64 last_packet;
int player_index; int player_index;
Uint8 rumble_left; Uint8 rumble_left;
Uint8 rumble_right; Uint8 rumble_right;
@@ -1037,7 +1037,7 @@ static SDL_bool HIDAPI_DriverPS4_UpdateDevice(SDL_HIDAPI_Device *device)
Uint8 data[USB_PACKET_LENGTH * 2]; Uint8 data[USB_PACKET_LENGTH * 2];
int size; int size;
int packet_count = 0; int packet_count = 0;
Uint32 now = SDL_GetTicks(); Uint64 now = SDL_GetTicks();
if (device->num_joysticks > 0) { if (device->num_joysticks > 0) {
joystick = SDL_JoystickFromInstanceID(device->joysticks[0]); joystick = SDL_JoystickFromInstanceID(device->joysticks[0]);
@@ -1089,7 +1089,7 @@ static SDL_bool HIDAPI_DriverPS4_UpdateDevice(SDL_HIDAPI_Device *device)
if (device->is_bluetooth) { if (device->is_bluetooth) {
if (packet_count == 0) { if (packet_count == 0) {
/* Check to see if it looks like the device disconnected */ /* Check to see if it looks like the device disconnected */
if (SDL_TICKS_PASSED(now, ctx->last_packet + BLUETOOTH_DISCONNECT_TIMEOUT_MS)) { if (now >= (ctx->last_packet + BLUETOOTH_DISCONNECT_TIMEOUT_MS)) {
/* Send an empty output report to tickle the Bluetooth stack */ /* Send an empty output report to tickle the Bluetooth stack */
HIDAPI_DriverPS4_TickleBluetooth(device); HIDAPI_DriverPS4_TickleBluetooth(device);
} }
@@ -1106,7 +1106,7 @@ static SDL_bool HIDAPI_DriverPS4_UpdateDevice(SDL_HIDAPI_Device *device)
if (packet_count == 0) { if (packet_count == 0) {
if (device->num_joysticks > 0) { if (device->num_joysticks > 0) {
/* Check to see if it looks like the device disconnected */ /* Check to see if it looks like the device disconnected */
if (SDL_TICKS_PASSED(now, ctx->last_packet + BLUETOOTH_DISCONNECT_TIMEOUT_MS)) { if (now >= (ctx->last_packet + BLUETOOTH_DISCONNECT_TIMEOUT_MS)) {
HIDAPI_JoystickDisconnected(device, device->joysticks[0]); HIDAPI_JoystickDisconnected(device, device->joysticks[0]);
} }
} }
+4 -4
View File
@@ -215,7 +215,7 @@ typedef struct
SDL_bool hardware_calibration; SDL_bool hardware_calibration;
IMUCalibrationData calibration[6]; IMUCalibrationData calibration[6];
Uint16 firmware_version; Uint16 firmware_version;
Uint32 last_packet; Uint64 last_packet;
int player_index; int player_index;
SDL_bool player_lights; SDL_bool player_lights;
Uint8 rumble_left; Uint8 rumble_left;
@@ -703,7 +703,7 @@ static void HIDAPI_DriverPS5_CheckPendingLEDReset(SDL_HIDAPI_Device *device)
packet->rgucSensorTimestamp[1], packet->rgucSensorTimestamp[1],
packet->rgucSensorTimestamp[2], packet->rgucSensorTimestamp[2],
packet->rgucSensorTimestamp[3]); packet->rgucSensorTimestamp[3]);
if (SDL_TICKS_PASSED(timestamp, connection_complete)) { if ((Sint32)(connection_complete - timestamp) <= 0) {
led_reset_complete = SDL_TRUE; led_reset_complete = SDL_TRUE;
} }
} else { } else {
@@ -1305,7 +1305,7 @@ static SDL_bool HIDAPI_DriverPS5_UpdateDevice(SDL_HIDAPI_Device *device)
Uint8 data[USB_PACKET_LENGTH * 2]; Uint8 data[USB_PACKET_LENGTH * 2];
int size; int size;
int packet_count = 0; int packet_count = 0;
Uint32 now = SDL_GetTicks(); Uint64 now = SDL_GetTicks();
if (device->num_joysticks > 0) { if (device->num_joysticks > 0) {
joystick = SDL_JoystickFromInstanceID(device->joysticks[0]); joystick = SDL_JoystickFromInstanceID(device->joysticks[0]);
@@ -1365,7 +1365,7 @@ static SDL_bool HIDAPI_DriverPS5_UpdateDevice(SDL_HIDAPI_Device *device)
if (device->is_bluetooth) { if (device->is_bluetooth) {
if (packet_count == 0) { if (packet_count == 0) {
/* Check to see if it looks like the device disconnected */ /* Check to see if it looks like the device disconnected */
if (SDL_TICKS_PASSED(now, ctx->last_packet + BLUETOOTH_DISCONNECT_TIMEOUT_MS)) { if (now >= (ctx->last_packet + BLUETOOTH_DISCONNECT_TIMEOUT_MS)) {
/* Send an empty output report to tickle the Bluetooth stack */ /* Send an empty output report to tickle the Bluetooth stack */
HIDAPI_DriverPS5_TickleBluetooth(device); HIDAPI_DriverPS5_TickleBluetooth(device);
} }
+4 -4
View File
@@ -78,13 +78,13 @@ typedef struct
SDL_JoystickPowerLevel battery_level; SDL_JoystickPowerLevel battery_level;
SDL_bool charging; SDL_bool charging;
Uint32 last_battery_query_time; Uint64 last_battery_query_time;
SDL_bool rumble_report_pending; SDL_bool rumble_report_pending;
SDL_bool rumble_update_pending; SDL_bool rumble_update_pending;
Uint8 left_motor_amplitude; Uint8 left_motor_amplitude;
Uint8 right_motor_amplitude; Uint8 right_motor_amplitude;
Uint32 last_rumble_time; Uint64 last_rumble_time;
Uint8 last_state[USB_PACKET_LENGTH]; Uint8 last_state[USB_PACKET_LENGTH];
} SDL_DriverShield_Context; } SDL_DriverShield_Context;
@@ -541,14 +541,14 @@ static SDL_bool HIDAPI_DriverShield_UpdateDevice(SDL_HIDAPI_Device *device)
} }
/* Ask for battery state again if we're due for an update */ /* Ask for battery state again if we're due for an update */
if (joystick && SDL_TICKS_PASSED(SDL_GetTicks(), ctx->last_battery_query_time + BATTERY_POLL_INTERVAL_MS)) { if (joystick && SDL_GetTicks() >= (ctx->last_battery_query_time + BATTERY_POLL_INTERVAL_MS)) {
ctx->last_battery_query_time = SDL_GetTicks(); ctx->last_battery_query_time = SDL_GetTicks();
HIDAPI_DriverShield_SendCommand(device, CMD_BATTERY_STATE, NULL, 0); HIDAPI_DriverShield_SendCommand(device, CMD_BATTERY_STATE, NULL, 0);
} }
/* Retransmit rumble packets if they've lasted longer than the hardware supports */ /* Retransmit rumble packets if they've lasted longer than the hardware supports */
if ((ctx->left_motor_amplitude != 0 || ctx->right_motor_amplitude != 0) && if ((ctx->left_motor_amplitude != 0 || ctx->right_motor_amplitude != 0) &&
SDL_TICKS_PASSED(SDL_GetTicks(), ctx->last_rumble_time + RUMBLE_REFRESH_INTERVAL_MS)) { SDL_GetTicks() >= (ctx->last_rumble_time + RUMBLE_REFRESH_INTERVAL_MS)) {
ctx->rumble_update_pending = SDL_TRUE; ctx->rumble_update_pending = SDL_TRUE;
HIDAPI_DriverShield_SendNextRumble(device); HIDAPI_DriverShield_SendNextRumble(device);
} }
+40 -42
View File
@@ -254,18 +254,18 @@ typedef struct
SwitchCommonOutputPacket_t m_RumblePacket; SwitchCommonOutputPacket_t m_RumblePacket;
Uint8 m_rgucReadBuffer[k_unSwitchMaxOutputPacketLength]; Uint8 m_rgucReadBuffer[k_unSwitchMaxOutputPacketLength];
SDL_bool m_bRumbleActive; SDL_bool m_bRumbleActive;
Uint32 m_unRumbleSent; Uint64 m_ulRumbleSent;
SDL_bool m_bRumblePending; SDL_bool m_bRumblePending;
SDL_bool m_bRumbleZeroPending; SDL_bool m_bRumbleZeroPending;
Uint32 m_unRumblePending; Uint32 m_unRumblePending;
SDL_bool m_bReportSensors; SDL_bool m_bReportSensors;
SDL_bool m_bHasSensorData; SDL_bool m_bHasSensorData;
Uint32 m_unLastInput; Uint64 m_ulLastInput;
Uint32 m_unLastIMUReset; Uint64 m_ulLastIMUReset;
Uint32 m_unIMUSampleTimestamp; Uint64 m_ulIMUSampleTimestampNS;
Uint32 m_unIMUSamples; Uint32 m_unIMUSamples;
Uint32 m_unIMUUpdateIntervalUS; Uint64 m_ulIMUUpdateIntervalNS;
Uint64 m_ulTimestampUS; Uint64 m_ulTimestampNS;
SDL_bool m_bVerticalMode; SDL_bool m_bVerticalMode;
SwitchInputOnlyControllerStatePacket_t m_lastInputOnlyState; SwitchInputOnlyControllerStatePacket_t m_lastInputOnlyState;
@@ -329,8 +329,7 @@ static int WriteOutput(SDL_DriverSwitch_Context *ctx, const Uint8 *data, int siz
static SwitchSubcommandInputPacket_t *ReadSubcommandReply(SDL_DriverSwitch_Context *ctx, ESwitchSubcommandIDs expectedID) static SwitchSubcommandInputPacket_t *ReadSubcommandReply(SDL_DriverSwitch_Context *ctx, ESwitchSubcommandIDs expectedID)
{ {
/* Average response time for messages is ~30ms */ /* Average response time for messages is ~30ms */
Uint32 TimeoutMs = 100; Uint64 endTicks = SDL_GetTicks() + 100;
Uint32 startTicks = SDL_GetTicks();
int nRead = 0; int nRead = 0;
while ((nRead = ReadInput(ctx)) != -1) { while ((nRead = ReadInput(ctx)) != -1) {
@@ -345,7 +344,7 @@ static SwitchSubcommandInputPacket_t *ReadSubcommandReply(SDL_DriverSwitch_Conte
SDL_Delay(1); SDL_Delay(1);
} }
if (SDL_TICKS_PASSED(SDL_GetTicks(), startTicks + TimeoutMs)) { if (SDL_GetTicks() >= endTicks) {
break; break;
} }
} }
@@ -355,8 +354,7 @@ static SwitchSubcommandInputPacket_t *ReadSubcommandReply(SDL_DriverSwitch_Conte
static SDL_bool ReadProprietaryReply(SDL_DriverSwitch_Context *ctx, ESwitchProprietaryCommandIDs expectedID) static SDL_bool ReadProprietaryReply(SDL_DriverSwitch_Context *ctx, ESwitchProprietaryCommandIDs expectedID)
{ {
/* Average response time for messages is ~30ms */ /* Average response time for messages is ~30ms */
Uint32 TimeoutMs = 100; Uint64 endTicks = SDL_GetTicks() + 100;
Uint32 startTicks = SDL_GetTicks();
int nRead = 0; int nRead = 0;
while ((nRead = ReadInput(ctx)) != -1) { while ((nRead = ReadInput(ctx)) != -1) {
@@ -368,7 +366,7 @@ static SDL_bool ReadProprietaryReply(SDL_DriverSwitch_Context *ctx, ESwitchPropr
SDL_Delay(1); SDL_Delay(1);
} }
if (SDL_TICKS_PASSED(SDL_GetTicks(), startTicks + TimeoutMs)) { if (SDL_GetTicks() >= endTicks) {
break; break;
} }
} }
@@ -536,7 +534,7 @@ static SDL_bool WriteRumble(SDL_DriverSwitch_Context *ctx)
ctx->m_nCommandNumber = (ctx->m_nCommandNumber + 1) & 0xF; ctx->m_nCommandNumber = (ctx->m_nCommandNumber + 1) & 0xF;
/* Refresh the rumble state periodically */ /* Refresh the rumble state periodically */
ctx->m_unRumbleSent = SDL_GetTicks(); ctx->m_ulRumbleSent = SDL_GetTicks();
return WritePacket(ctx, (Uint8 *)&ctx->m_RumblePacket, sizeof(ctx->m_RumblePacket)); return WritePacket(ctx, (Uint8 *)&ctx->m_RumblePacket, sizeof(ctx->m_RumblePacket));
} }
@@ -1370,8 +1368,8 @@ static SDL_bool HIDAPI_DriverSwitch_OpenJoystick(SDL_HIDAPI_Device *device, SDL_
/* Set up for input */ /* Set up for input */
ctx->m_bSyncWrite = SDL_FALSE; ctx->m_bSyncWrite = SDL_FALSE;
ctx->m_unLastIMUReset = ctx->m_unLastInput = SDL_GetTicks(); ctx->m_ulLastIMUReset = ctx->m_ulLastInput = SDL_GetTicks();
ctx->m_unIMUUpdateIntervalUS = 5 * 1000; /* Start off at 5 ms update rate */ ctx->m_ulIMUUpdateIntervalNS = SDL_MS_TO_NS(5); /* Start off at 5 ms update rate */
/* Set up for vertical mode */ /* Set up for vertical mode */
ctx->m_bVerticalMode = SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_VERTICAL_JOY_CONS, SDL_FALSE); ctx->m_bVerticalMode = SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_VERTICAL_JOY_CONS, SDL_FALSE);
@@ -1410,7 +1408,7 @@ static int HIDAPI_DriverSwitch_ActuallyRumbleJoystick(SDL_DriverSwitch_Context *
static int HIDAPI_DriverSwitch_SendPendingRumble(SDL_DriverSwitch_Context *ctx) static int HIDAPI_DriverSwitch_SendPendingRumble(SDL_DriverSwitch_Context *ctx)
{ {
if (!SDL_TICKS_PASSED(SDL_GetTicks(), ctx->m_unRumbleSent + RUMBLE_WRITE_FREQUENCY_MS)) { if (SDL_GetTicks() < (ctx->m_ulRumbleSent + RUMBLE_WRITE_FREQUENCY_MS)) {
return 0; return 0;
} }
@@ -1419,7 +1417,7 @@ static int HIDAPI_DriverSwitch_SendPendingRumble(SDL_DriverSwitch_Context *ctx)
Uint16 high_frequency_rumble = (Uint16)ctx->m_unRumblePending; Uint16 high_frequency_rumble = (Uint16)ctx->m_unRumblePending;
#ifdef DEBUG_RUMBLE #ifdef DEBUG_RUMBLE
SDL_Log("Sent pending rumble %d/%d, %d ms after previous rumble\n", low_frequency_rumble, high_frequency_rumble, SDL_GetTicks() - ctx->m_unRumbleSent); SDL_Log("Sent pending rumble %d/%d, %d ms after previous rumble\n", low_frequency_rumble, high_frequency_rumble, SDL_GetTicks() - ctx->m_ulRumbleSent);
#endif #endif
ctx->m_bRumblePending = SDL_FALSE; ctx->m_bRumblePending = SDL_FALSE;
ctx->m_unRumblePending = 0; ctx->m_unRumblePending = 0;
@@ -1431,7 +1429,7 @@ static int HIDAPI_DriverSwitch_SendPendingRumble(SDL_DriverSwitch_Context *ctx)
ctx->m_bRumbleZeroPending = SDL_FALSE; ctx->m_bRumbleZeroPending = SDL_FALSE;
#ifdef DEBUG_RUMBLE #ifdef DEBUG_RUMBLE
SDL_Log("Sent pending zero rumble, %d ms after previous rumble\n", SDL_GetTicks() - ctx->m_unRumbleSent); SDL_Log("Sent pending zero rumble, %d ms after previous rumble\n", SDL_GetTicks() - ctx->m_ulRumbleSent);
#endif #endif
return HIDAPI_DriverSwitch_ActuallyRumbleJoystick(ctx, 0, 0); return HIDAPI_DriverSwitch_ActuallyRumbleJoystick(ctx, 0, 0);
} }
@@ -1463,7 +1461,7 @@ static int HIDAPI_DriverSwitch_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joy
} }
} }
if (!SDL_TICKS_PASSED(SDL_GetTicks(), ctx->m_unRumbleSent + RUMBLE_WRITE_FREQUENCY_MS)) { if (SDL_GetTicks() < (ctx->m_ulRumbleSent + RUMBLE_WRITE_FREQUENCY_MS)) {
if (low_frequency_rumble || high_frequency_rumble) { if (low_frequency_rumble || high_frequency_rumble) {
Uint32 unRumblePending = ((Uint32)low_frequency_rumble << 16) | high_frequency_rumble; Uint32 unRumblePending = ((Uint32)low_frequency_rumble << 16) | high_frequency_rumble;
@@ -1522,7 +1520,7 @@ static int HIDAPI_DriverSwitch_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *devi
SetIMUEnabled(ctx, enabled); SetIMUEnabled(ctx, enabled);
ctx->m_bReportSensors = enabled; ctx->m_bReportSensors = enabled;
ctx->m_unIMUSamples = 0; ctx->m_unIMUSamples = 0;
ctx->m_unIMUSampleTimestamp = SDL_GetTicks(); ctx->m_ulIMUSampleTimestampNS = SDL_GetTicksNS();
return 0; return 0;
} }
@@ -1988,22 +1986,22 @@ static void HandleFullControllerState(SDL_Joystick *joystick, SDL_DriverSwitch_C
/* We got three IMU samples, calculate the IMU update rate and timestamps */ /* We got three IMU samples, calculate the IMU update rate and timestamps */
ctx->m_unIMUSamples += 3; ctx->m_unIMUSamples += 3;
if (ctx->m_unIMUSamples >= IMU_UPDATE_RATE_SAMPLE_FREQUENCY) { if (ctx->m_unIMUSamples >= IMU_UPDATE_RATE_SAMPLE_FREQUENCY) {
Uint32 now = SDL_GetTicks(); Uint64 now = SDL_GetTicksNS();
Uint32 elapsed = (now - ctx->m_unIMUSampleTimestamp); Uint64 elapsed = (now - ctx->m_ulIMUSampleTimestampNS);
if (elapsed > 0) { if (elapsed > 0) {
ctx->m_unIMUUpdateIntervalUS = (elapsed * 1000) / ctx->m_unIMUSamples; ctx->m_ulIMUUpdateIntervalNS = elapsed / ctx->m_unIMUSamples;
} }
ctx->m_unIMUSamples = 0; ctx->m_unIMUSamples = 0;
ctx->m_unIMUSampleTimestamp = now; ctx->m_ulIMUSampleTimestampNS = now;
} }
ctx->m_ulTimestampUS += ctx->m_unIMUUpdateIntervalUS; ctx->m_ulTimestampNS += ctx->m_ulIMUUpdateIntervalNS;
timestamp[0] = ctx->m_ulTimestampUS; timestamp[0] = SDL_NS_TO_US(ctx->m_ulTimestampNS);
ctx->m_ulTimestampUS += ctx->m_unIMUUpdateIntervalUS; ctx->m_ulTimestampNS += ctx->m_ulIMUUpdateIntervalNS;
timestamp[1] = ctx->m_ulTimestampUS; timestamp[1] = SDL_NS_TO_US(ctx->m_ulTimestampNS);
ctx->m_ulTimestampUS += ctx->m_unIMUUpdateIntervalUS; ctx->m_ulTimestampNS += ctx->m_ulIMUUpdateIntervalNS;
timestamp[2] = ctx->m_ulTimestampUS; timestamp[2] = SDL_NS_TO_US(ctx->m_ulTimestampNS);
if (!ctx->device->parent || if (!ctx->device->parent ||
ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_JoyConRight) { ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_JoyConRight) {
@@ -2042,10 +2040,10 @@ static void HandleFullControllerState(SDL_Joystick *joystick, SDL_DriverSwitch_C
} else if (ctx->m_bHasSensorData) { } else if (ctx->m_bHasSensorData) {
/* Uh oh, someone turned off the IMU? */ /* Uh oh, someone turned off the IMU? */
const Uint32 IMU_RESET_DELAY_MS = 3000; const int IMU_RESET_DELAY_MS = 3000;
Uint32 now = SDL_GetTicks(); Uint64 now = SDL_GetTicks();
if (SDL_TICKS_PASSED(now, ctx->m_unLastIMUReset + IMU_RESET_DELAY_MS)) { if (now >= (ctx->m_ulLastIMUReset + IMU_RESET_DELAY_MS)) {
SDL_HIDAPI_Device *device = ctx->device; SDL_HIDAPI_Device *device = ctx->device;
if (device->updating) { if (device->updating) {
@@ -2057,7 +2055,7 @@ static void HandleFullControllerState(SDL_Joystick *joystick, SDL_DriverSwitch_C
if (device->updating) { if (device->updating) {
SDL_LockMutex(device->dev_lock); SDL_LockMutex(device->dev_lock);
} }
ctx->m_unLastIMUReset = now; ctx->m_ulLastIMUReset = now;
} }
} else { } else {
@@ -2074,7 +2072,7 @@ static SDL_bool HIDAPI_DriverSwitch_UpdateDevice(SDL_HIDAPI_Device *device)
SDL_Joystick *joystick = NULL; SDL_Joystick *joystick = NULL;
int size; int size;
int packet_count = 0; int packet_count = 0;
Uint32 now = SDL_GetTicks(); Uint64 now = SDL_GetTicks();
if (device->num_joysticks > 0) { if (device->num_joysticks > 0) {
joystick = SDL_JoystickFromInstanceID(device->joysticks[0]); joystick = SDL_JoystickFromInstanceID(device->joysticks[0]);
@@ -2085,7 +2083,7 @@ static SDL_bool HIDAPI_DriverSwitch_UpdateDevice(SDL_HIDAPI_Device *device)
HIDAPI_DumpPacket("Nintendo Switch packet: size = %d", ctx->m_rgucReadBuffer, size); HIDAPI_DumpPacket("Nintendo Switch packet: size = %d", ctx->m_rgucReadBuffer, size);
#endif #endif
++packet_count; ++packet_count;
ctx->m_unLastInput = now; ctx->m_ulLastInput = now;
if (joystick == NULL) { if (joystick == NULL) {
continue; continue;
@@ -2111,14 +2109,14 @@ static SDL_bool HIDAPI_DriverSwitch_UpdateDevice(SDL_HIDAPI_Device *device)
if (packet_count == 0) { if (packet_count == 0) {
if (!ctx->m_bInputOnly && !device->is_bluetooth && if (!ctx->m_bInputOnly && !device->is_bluetooth &&
ctx->device->product_id != USB_PRODUCT_NINTENDO_SWITCH_JOYCON_GRIP) { ctx->device->product_id != USB_PRODUCT_NINTENDO_SWITCH_JOYCON_GRIP) {
const Uint32 INPUT_WAIT_TIMEOUT_MS = 100; const int INPUT_WAIT_TIMEOUT_MS = 100;
if (SDL_TICKS_PASSED(now, ctx->m_unLastInput + INPUT_WAIT_TIMEOUT_MS)) { if (now >= (ctx->m_ulLastInput + INPUT_WAIT_TIMEOUT_MS)) {
/* Steam may have put the controller back into non-reporting mode */ /* Steam may have put the controller back into non-reporting mode */
WriteProprietary(ctx, k_eSwitchProprietaryCommandIDs_ForceUSB, NULL, 0, SDL_FALSE); WriteProprietary(ctx, k_eSwitchProprietaryCommandIDs_ForceUSB, NULL, 0, SDL_FALSE);
} }
} else if (device->is_bluetooth) { } else if (device->is_bluetooth) {
const Uint32 INPUT_WAIT_TIMEOUT_MS = 3000; const int INPUT_WAIT_TIMEOUT_MS = 3000;
if (SDL_TICKS_PASSED(now, ctx->m_unLastInput + INPUT_WAIT_TIMEOUT_MS)) { if (now >= (ctx->m_ulLastInput + INPUT_WAIT_TIMEOUT_MS)) {
/* Bluetooth may have disconnected, try reopening the controller */ /* Bluetooth may have disconnected, try reopening the controller */
size = -1; size = -1;
} }
@@ -2128,9 +2126,9 @@ static SDL_bool HIDAPI_DriverSwitch_UpdateDevice(SDL_HIDAPI_Device *device)
if (ctx->m_bRumblePending || ctx->m_bRumbleZeroPending) { if (ctx->m_bRumblePending || ctx->m_bRumbleZeroPending) {
HIDAPI_DriverSwitch_SendPendingRumble(ctx); HIDAPI_DriverSwitch_SendPendingRumble(ctx);
} else if (ctx->m_bRumbleActive && } else if (ctx->m_bRumbleActive &&
SDL_TICKS_PASSED(now, ctx->m_unRumbleSent + RUMBLE_REFRESH_FREQUENCY_MS)) { now >= (ctx->m_ulRumbleSent + RUMBLE_REFRESH_FREQUENCY_MS)) {
#ifdef DEBUG_RUMBLE #ifdef DEBUG_RUMBLE
SDL_Log("Sent continuing rumble, %d ms after previous rumble\n", now - ctx->m_unRumbleSent); SDL_Log("Sent continuing rumble, %d ms after previous rumble\n", now - ctx->m_ulRumbleSent);
#endif #endif
WriteRumble(ctx); WriteRumble(ctx);
} }
+15 -21
View File
@@ -142,9 +142,9 @@ typedef struct
Uint8 m_ucMotionPlusMode; Uint8 m_ucMotionPlusMode;
SDL_bool m_bReportSensors; SDL_bool m_bReportSensors;
Uint8 m_rgucReadBuffer[k_unWiiPacketDataLength]; Uint8 m_rgucReadBuffer[k_unWiiPacketDataLength];
Uint32 m_unLastInput; Uint64 m_ulLastInput;
Uint32 m_unLastStatus; Uint64 m_ulLastStatus;
Uint32 m_unNextMotionPlusCheck; Uint64 m_ulNextMotionPlusCheck;
SDL_bool m_bDisconnected; SDL_bool m_bDisconnected;
struct StickCalibrationData struct StickCalibrationData
@@ -225,8 +225,7 @@ static SDL_bool WriteOutput(SDL_DriverWii_Context *ctx, const Uint8 *data, int s
static SDL_bool ReadInputSync(SDL_DriverWii_Context *ctx, EWiiInputReportIDs expectedID, SDL_bool (*isMine)(const Uint8 *)) static SDL_bool ReadInputSync(SDL_DriverWii_Context *ctx, EWiiInputReportIDs expectedID, SDL_bool (*isMine)(const Uint8 *))
{ {
Uint32 TimeoutMs = 250; /* Seeing successful reads after about 200 ms */ Uint64 endTicks = SDL_GetTicks() + 250; /* Seeing successful reads after about 200 ms */
Uint32 startTicks = SDL_GetTicks();
int nRead = 0; int nRead = 0;
while ((nRead = ReadInput(ctx)) != -1) { while ((nRead = ReadInput(ctx)) != -1) {
@@ -235,7 +234,7 @@ static SDL_bool ReadInputSync(SDL_DriverWii_Context *ctx, EWiiInputReportIDs exp
return SDL_TRUE; return SDL_TRUE;
} }
} else { } else {
if (SDL_TICKS_PASSED(SDL_GetTicks(), startTicks + TimeoutMs)) { if (SDL_GetTicks() >= endTicks) {
break; break;
} }
SDL_Delay(1); SDL_Delay(1);
@@ -443,10 +442,7 @@ static SDL_bool NeedsPeriodicMotionPlusCheck(SDL_DriverWii_Context *ctx, SDL_boo
static void SchedulePeriodicMotionPlusCheck(SDL_DriverWii_Context *ctx) static void SchedulePeriodicMotionPlusCheck(SDL_DriverWii_Context *ctx)
{ {
ctx->m_unNextMotionPlusCheck = SDL_GetTicks() + MOTION_PLUS_UPDATE_TIME_MS; ctx->m_ulNextMotionPlusCheck = SDL_GetTicks() + MOTION_PLUS_UPDATE_TIME_MS;
if (!ctx->m_unNextMotionPlusCheck) {
ctx->m_unNextMotionPlusCheck = 1;
}
} }
static void CheckMotionPlusConnection(SDL_DriverWii_Context *ctx) static void CheckMotionPlusConnection(SDL_DriverWii_Context *ctx)
@@ -807,7 +803,7 @@ static SDL_bool HIDAPI_DriverWii_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joy
} }
joystick->naxes = SDL_CONTROLLER_AXIS_MAX; joystick->naxes = SDL_CONTROLLER_AXIS_MAX;
ctx->m_unLastInput = SDL_GetTicks(); ctx->m_ulLastInput = SDL_GetTicks();
return SDL_TRUE; return SDL_TRUE;
} }
@@ -1433,7 +1429,7 @@ static void HandleStatus(SDL_DriverWii_Context *ctx, SDL_Joystick *joystick)
* Motion Plus packets. * Motion Plus packets.
*/ */
if (NeedsPeriodicMotionPlusCheck(ctx, SDL_TRUE)) { if (NeedsPeriodicMotionPlusCheck(ctx, SDL_TRUE)) {
ctx->m_unNextMotionPlusCheck = SDL_GetTicks(); ctx->m_ulNextMotionPlusCheck = SDL_GetTicks();
} }
} else if (hadExtension != hasExtension) { } else if (hadExtension != hasExtension) {
@@ -1568,7 +1564,7 @@ static SDL_bool HIDAPI_DriverWii_UpdateDevice(SDL_HIDAPI_Device *device)
SDL_DriverWii_Context *ctx = (SDL_DriverWii_Context *)device->context; SDL_DriverWii_Context *ctx = (SDL_DriverWii_Context *)device->context;
SDL_Joystick *joystick = NULL; SDL_Joystick *joystick = NULL;
int size; int size;
Uint32 now; Uint64 now;
if (device->num_joysticks > 0) { if (device->num_joysticks > 0) {
joystick = SDL_JoystickFromInstanceID(device->joysticks[0]); joystick = SDL_JoystickFromInstanceID(device->joysticks[0]);
@@ -1582,7 +1578,7 @@ static SDL_bool HIDAPI_DriverWii_UpdateDevice(SDL_HIDAPI_Device *device)
if (joystick) { if (joystick) {
HandleInput(ctx, joystick); HandleInput(ctx, joystick);
} }
ctx->m_unLastInput = now; ctx->m_ulLastInput = now;
} }
/* Check to see if we've lost connection to the controller. /* Check to see if we've lost connection to the controller.
@@ -1591,7 +1587,7 @@ static SDL_bool HIDAPI_DriverWii_UpdateDevice(SDL_HIDAPI_Device *device)
{ {
SDL_COMPILE_TIME_ASSERT(ENABLE_CONTINUOUS_REPORTING, ENABLE_CONTINUOUS_REPORTING); SDL_COMPILE_TIME_ASSERT(ENABLE_CONTINUOUS_REPORTING, ENABLE_CONTINUOUS_REPORTING);
} }
if (SDL_TICKS_PASSED(now, ctx->m_unLastInput + INPUT_WAIT_TIMEOUT_MS)) { if (now >= (ctx->m_ulLastInput + INPUT_WAIT_TIMEOUT_MS)) {
/* Bluetooth may have disconnected, try reopening the controller */ /* Bluetooth may have disconnected, try reopening the controller */
size = -1; size = -1;
} }
@@ -1601,26 +1597,24 @@ static SDL_bool HIDAPI_DriverWii_UpdateDevice(SDL_HIDAPI_Device *device)
if (ctx->m_eExtensionControllerType != k_eWiiExtensionControllerType_WiiUPro) { if (ctx->m_eExtensionControllerType != k_eWiiExtensionControllerType_WiiUPro) {
/* Check to see if the Motion Plus extension status has changed */ /* Check to see if the Motion Plus extension status has changed */
if (ctx->m_unNextMotionPlusCheck && if (ctx->m_ulNextMotionPlusCheck && now >= ctx->m_ulNextMotionPlusCheck) {
SDL_TICKS_PASSED(now, ctx->m_unNextMotionPlusCheck)) {
CheckMotionPlusConnection(ctx); CheckMotionPlusConnection(ctx);
if (NeedsPeriodicMotionPlusCheck(ctx, SDL_FALSE)) { if (NeedsPeriodicMotionPlusCheck(ctx, SDL_FALSE)) {
SchedulePeriodicMotionPlusCheck(ctx); SchedulePeriodicMotionPlusCheck(ctx);
} else { } else {
ctx->m_unNextMotionPlusCheck = 0; ctx->m_ulNextMotionPlusCheck = 0;
} }
} }
/* Request a status update periodically to make sure our battery value is up to date */ /* Request a status update periodically to make sure our battery value is up to date */
if (!ctx->m_unLastStatus || if (!ctx->m_ulLastStatus || now >= (ctx->m_ulLastStatus + STATUS_UPDATE_TIME_MS)) {
SDL_TICKS_PASSED(now, ctx->m_unLastStatus + STATUS_UPDATE_TIME_MS)) {
Uint8 data[2]; Uint8 data[2];
data[0] = k_eWiiOutputReportIDs_StatusRequest; data[0] = k_eWiiOutputReportIDs_StatusRequest;
data[1] = ctx->m_bRumbleActive; data[1] = ctx->m_bRumbleActive;
WriteOutput(ctx, data, sizeof(data), SDL_FALSE); WriteOutput(ctx, data, sizeof(data), SDL_FALSE);
ctx->m_unLastStatus = now; ctx->m_ulLastStatus = now;
} }
} }
} }
+7 -7
View File
@@ -117,9 +117,9 @@ typedef struct
SDL_bool bluetooth; SDL_bool bluetooth;
SDL_XboxOneInitState init_state; SDL_XboxOneInitState init_state;
int init_packet; int init_packet;
Uint32 start_time; Uint64 start_time;
Uint8 sequence; Uint8 sequence;
Uint32 send_time; Uint64 send_time;
SDL_bool has_guide_packet; SDL_bool has_guide_packet;
SDL_bool has_color_led; SDL_bool has_color_led;
SDL_bool has_paddles; SDL_bool has_paddles;
@@ -132,7 +132,7 @@ typedef struct
Uint8 left_trigger_rumble; Uint8 left_trigger_rumble;
Uint8 right_trigger_rumble; Uint8 right_trigger_rumble;
SDL_XboxOneRumbleState rumble_state; SDL_XboxOneRumbleState rumble_state;
Uint32 rumble_time; Uint64 rumble_time;
SDL_bool rumble_pending; SDL_bool rumble_pending;
Uint8 last_state[USB_PACKET_LENGTH]; Uint8 last_state[USB_PACKET_LENGTH];
} SDL_DriverXboxOne_Context; } SDL_DriverXboxOne_Context;
@@ -456,8 +456,8 @@ static int HIDAPI_DriverXboxOne_UpdateRumble(SDL_HIDAPI_Device *device)
} }
if (ctx->rumble_state == XBOX_ONE_RUMBLE_STATE_BUSY) { if (ctx->rumble_state == XBOX_ONE_RUMBLE_STATE_BUSY) {
const Uint32 RUMBLE_BUSY_TIME_MS = ctx->bluetooth ? 50 : 10; const int RUMBLE_BUSY_TIME_MS = ctx->bluetooth ? 50 : 10;
if (SDL_TICKS_PASSED(SDL_GetTicks(), ctx->rumble_time + RUMBLE_BUSY_TIME_MS)) { if (SDL_GetTicks() >= (ctx->rumble_time + RUMBLE_BUSY_TIME_MS)) {
ctx->rumble_time = 0; ctx->rumble_time = 0;
ctx->rumble_state = XBOX_ONE_RUMBLE_STATE_IDLE; ctx->rumble_state = XBOX_ONE_RUMBLE_STATE_IDLE;
} }
@@ -1087,7 +1087,7 @@ static SDL_bool HIDAPI_DriverXboxOne_UpdateInitState(SDL_HIDAPI_Device *device,
#endif #endif
break; break;
case XBOX_ONE_INIT_STATE_NEGOTIATING: case XBOX_ONE_INIT_STATE_NEGOTIATING:
if (SDL_TICKS_PASSED(SDL_GetTicks(), ctx->send_time + CONTROLLER_NEGOTIATION_TIMEOUT_MS)) { if (SDL_GetTicks() >= (ctx->send_time + CONTROLLER_NEGOTIATION_TIMEOUT_MS)) {
/* We haven't heard anything, let's move on */ /* We haven't heard anything, let's move on */
#ifdef DEBUG_JOYSTICK #ifdef DEBUG_JOYSTICK
SDL_Log("Init sequence %d timed out after %u ms\n", ctx->init_packet, (SDL_GetTicks() - ctx->send_time)); SDL_Log("Init sequence %d timed out after %u ms\n", ctx->init_packet, (SDL_GetTicks() - ctx->send_time));
@@ -1099,7 +1099,7 @@ static SDL_bool HIDAPI_DriverXboxOne_UpdateInitState(SDL_HIDAPI_Device *device,
} }
break; break;
case XBOX_ONE_INIT_STATE_PREPARE_INPUT: case XBOX_ONE_INIT_STATE_PREPARE_INPUT:
if (SDL_TICKS_PASSED(SDL_GetTicks(), ctx->send_time + CONTROLLER_PREPARE_INPUT_TIMEOUT_MS)) { if (SDL_GetTicks() >= (ctx->send_time + CONTROLLER_PREPARE_INPUT_TIMEOUT_MS)) {
#ifdef DEBUG_JOYSTICK #ifdef DEBUG_JOYSTICK
SDL_Log("Prepare input complete after %u ms\n", (SDL_GetTicks() - ctx->send_time)); SDL_Log("Prepare input complete after %u ms\n", (SDL_GetTicks() - ctx->send_time));
#endif #endif
+3 -3
View File
@@ -119,7 +119,7 @@ static SDL_joylist_item *SDL_joylist_tail = NULL;
static int numjoysticks = 0; static int numjoysticks = 0;
static int inotify_fd = -1; static int inotify_fd = -1;
static Uint32 last_joy_detect_time; static Uint64 last_joy_detect_time;
static time_t last_input_dir_mtime; static time_t last_input_dir_mtime;
static void FixupDeviceInfoForMapping(int fd, struct input_id *inpid) static void FixupDeviceInfoForMapping(int fd, struct input_id *inpid)
@@ -644,9 +644,9 @@ static int sort_entries(const void *_a, const void *_b)
static void LINUX_FallbackJoystickDetect(void) static void LINUX_FallbackJoystickDetect(void)
{ {
const Uint32 SDL_JOY_DETECT_INTERVAL_MS = 3000; /* Update every 3 seconds */ const Uint32 SDL_JOY_DETECT_INTERVAL_MS = 3000; /* Update every 3 seconds */
Uint32 now = SDL_GetTicks(); Uint64 now = SDL_GetTicks();
if (!last_joy_detect_time || SDL_TICKS_PASSED(now, last_joy_detect_time + SDL_JOY_DETECT_INTERVAL_MS)) { if (!last_joy_detect_time || now >= (last_joy_detect_time + SDL_JOY_DETECT_INTERVAL_MS)) {
struct stat sb; struct stat sb;
/* Opening input devices can generate synchronous device I/O, so avoid it if we can */ /* Opening input devices can generate synchronous device I/O, so avoid it if we can */
+3 -3
View File
@@ -129,7 +129,7 @@ struct joystick_hwdata
#ifdef SDL_JOYSTICK_RAWINPUT_MATCHING #ifdef SDL_JOYSTICK_RAWINPUT_MATCHING
Uint64 match_state; /* Lowest 16 bits for button states, higher 24 for 6 4bit axes */ Uint64 match_state; /* Lowest 16 bits for button states, higher 24 for 6 4bit axes */
Uint32 last_state_packet; Uint64 last_state_packet;
#endif #endif
#ifdef SDL_JOYSTICK_RAWINPUT_XINPUT #ifdef SDL_JOYSTICK_RAWINPUT_XINPUT
@@ -167,7 +167,7 @@ static const Uint16 subscribed_devices[] = {
static struct static struct
{ {
Uint32 last_state_packet; Uint64 last_state_packet;
SDL_Joystick *joystick; SDL_Joystick *joystick;
SDL_Joystick *last_joystick; SDL_Joystick *last_joystick;
} guide_button_candidate; } guide_button_candidate;
@@ -1808,7 +1808,7 @@ static void RAWINPUT_UpdateOtherAPIs(SDL_Joystick *joystick)
if (!correlated) { if (!correlated) {
if (!guide_button_candidate.joystick || if (!guide_button_candidate.joystick ||
(ctx->last_state_packet && (!guide_button_candidate.last_state_packet || (ctx->last_state_packet && (!guide_button_candidate.last_state_packet ||
SDL_TICKS_PASSED(ctx->last_state_packet, guide_button_candidate.last_state_packet)))) { ctx->last_state_packet >= guide_button_candidate.last_state_packet))) {
guide_button_candidate.joystick = joystick; guide_button_candidate.joystick = joystick;
guide_button_candidate.last_state_packet = ctx->last_state_packet; guide_button_candidate.last_state_packet = ctx->last_state_packet;
} }
+2 -2
View File
@@ -30,12 +30,12 @@
#if !TARGET_OS_TV #if !TARGET_OS_TV
/* turn off the battery monitor if it's been more than X ms since last check. */ /* turn off the battery monitor if it's been more than X ms since last check. */
static const int BATTERY_MONITORING_TIMEOUT = 3000; static const int BATTERY_MONITORING_TIMEOUT = 3000;
static Uint32 SDL_UIKitLastPowerInfoQuery = 0; static Uint64 SDL_UIKitLastPowerInfoQuery = 0;
void SDL_UIKit_UpdateBatteryMonitoring(void) void SDL_UIKit_UpdateBatteryMonitoring(void)
{ {
if (SDL_UIKitLastPowerInfoQuery) { if (SDL_UIKitLastPowerInfoQuery) {
if (SDL_TICKS_PASSED(SDL_GetTicks(), SDL_UIKitLastPowerInfoQuery + BATTERY_MONITORING_TIMEOUT)) { if (SDL_GetTicks() >= (SDL_UIKitLastPowerInfoQuery + BATTERY_MONITORING_TIMEOUT)) {
UIDevice *uidev = [UIDevice currentDevice]; UIDevice *uidev = [UIDevice currentDevice];
SDL_assert([uidev isBatteryMonitoringEnabled] == YES); SDL_assert([uidev isBatteryMonitoringEnabled] == YES);
[uidev setBatteryMonitoringEnabled:NO]; [uidev setBatteryMonitoringEnabled:NO];
+9 -9
View File
@@ -921,7 +921,7 @@ static void SDL_CalculateSimulatedVSyncInterval(SDL_Renderer *renderer, SDL_Wind
/* Pick a good default refresh rate */ /* Pick a good default refresh rate */
refresh_rate = 60; refresh_rate = 60;
} }
renderer->simulate_vsync_interval = (1000 / refresh_rate); renderer->simulate_vsync_interval_ns = (SDL_NS_PER_SECOND / refresh_rate);
} }
#endif /* !SDL_RENDER_DISABLED */ #endif /* !SDL_RENDER_DISABLED */
@@ -4188,24 +4188,24 @@ int SDL_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect,
static void SDL_RenderSimulateVSync(SDL_Renderer *renderer) static void SDL_RenderSimulateVSync(SDL_Renderer *renderer)
{ {
Uint32 now, elapsed; Uint64 now, elapsed;
const Uint32 interval = renderer->simulate_vsync_interval; const Uint64 interval = renderer->simulate_vsync_interval_ns;
if (!interval) { if (!interval) {
/* We can't do sub-ms delay, so just return here */ /* We can't do sub-ns delay, so just return here */
return; return;
} }
now = SDL_GetTicks(); now = SDL_GetTicksNS();
elapsed = (now - renderer->last_present); elapsed = (now - renderer->last_present);
if (elapsed < interval) { if (elapsed < interval) {
Uint32 duration = (interval - elapsed); Uint64 duration = (interval - elapsed);
SDL_Delay(duration); SDL_DelayNS(duration);
now = SDL_GetTicks(); now = SDL_GetTicksNS();
} }
elapsed = (now - renderer->last_present); elapsed = (now - renderer->last_present);
if (!renderer->last_present || elapsed > 1000) { if (!renderer->last_present || elapsed > SDL_NS_TO_MS(1000)) {
/* It's been too long, reset the presentation timeline */ /* It's been too long, reset the presentation timeline */
renderer->last_present = now; renderer->last_present = now;
} else { } else {
+2 -2
View File
@@ -209,8 +209,8 @@ struct SDL_Renderer
/* Whether we should simulate vsync */ /* Whether we should simulate vsync */
SDL_bool wanted_vsync; SDL_bool wanted_vsync;
SDL_bool simulate_vsync; SDL_bool simulate_vsync;
Uint32 simulate_vsync_interval; Uint64 simulate_vsync_interval_ns;
Uint32 last_present; Uint64 last_present;
/* The logical resolution for rendering */ /* The logical resolution for rendering */
int logical_w; int logical_w;
+39
View File
@@ -481,4 +481,43 @@ void SDL_DetachThread(SDL_Thread *thread)
} }
} }
int SDL_SemWait(SDL_sem *sem)
{
return SDL_SemWaitTimeoutNS(sem, SDL_MUTEX_MAXWAIT);
}
int SDL_SemTryWait(SDL_sem *sem)
{
return SDL_SemWaitTimeoutNS(sem, 0);
}
int SDL_SemWaitTimeout(SDL_sem *sem, Sint32 timeoutMS)
{
Sint64 timeoutNS;
if (timeoutMS >= 0) {
timeoutNS = SDL_MS_TO_NS(timeoutMS);
} else {
timeoutNS = -1;
}
return SDL_SemWaitTimeoutNS(sem, timeoutNS);
}
int SDL_CondWait(SDL_cond *cond, SDL_mutex *mutex)
{
return SDL_CondWaitTimeoutNS(cond, mutex, SDL_MUTEX_MAXWAIT);
}
int SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Sint32 timeoutMS)
{
Sint64 timeoutNS;
if (timeoutMS >= 0) {
timeoutNS = SDL_MS_TO_NS(timeoutMS);
} else {
timeoutNS = -1;
}
return SDL_CondWaitTimeoutNS(cond, mutex, timeoutNS);
}
/* vi: set ts=4 sw=4 expandtab: */ /* vi: set ts=4 sw=4 expandtab: */
+4 -15
View File
@@ -37,8 +37,7 @@
#define SDL_DestroyCond_generic SDL_DestroyCond #define SDL_DestroyCond_generic SDL_DestroyCond
#define SDL_CondSignal_generic SDL_CondSignal #define SDL_CondSignal_generic SDL_CondSignal
#define SDL_CondBroadcast_generic SDL_CondBroadcast #define SDL_CondBroadcast_generic SDL_CondBroadcast
#define SDL_CondWait_generic SDL_CondWait #define SDL_CondWaitTimeoutNS_generic SDL_CondWaitTimeoutNS
#define SDL_CondWaitTimeout_generic SDL_CondWaitTimeout
#endif #endif
typedef struct SDL_cond_generic typedef struct SDL_cond_generic
@@ -148,7 +147,7 @@ int SDL_CondBroadcast_generic(SDL_cond *_cond)
return 0; return 0;
} }
/* Wait on the condition variable for at most 'ms' milliseconds. /* Wait on the condition variable for at most 'timeoutNS' nanoseconds.
The mutex must be locked before entering this function! The mutex must be locked before entering this function!
The mutex is unlocked during the wait, and locked again after the wait. The mutex is unlocked during the wait, and locked again after the wait.
@@ -169,7 +168,7 @@ Thread B:
SDL_CondSignal(cond); SDL_CondSignal(cond);
SDL_UnlockMutex(lock); SDL_UnlockMutex(lock);
*/ */
int SDL_CondWaitTimeout_generic(SDL_cond *_cond, SDL_mutex *mutex, Uint32 ms) int SDL_CondWaitTimeoutNS_generic(SDL_cond *_cond, SDL_mutex *mutex, Sint64 timeoutNS)
{ {
SDL_cond_generic *cond = (SDL_cond_generic *)_cond; SDL_cond_generic *cond = (SDL_cond_generic *)_cond;
int retval; int retval;
@@ -190,11 +189,7 @@ int SDL_CondWaitTimeout_generic(SDL_cond *_cond, SDL_mutex *mutex, Uint32 ms)
SDL_UnlockMutex(mutex); SDL_UnlockMutex(mutex);
/* Wait for a signal */ /* Wait for a signal */
if (ms == SDL_MUTEX_MAXWAIT) { retval = SDL_SemWaitTimeoutNS(cond->wait_sem, timeoutNS);
retval = SDL_SemWait(cond->wait_sem);
} else {
retval = SDL_SemWaitTimeout(cond->wait_sem, ms);
}
/* Let the signaler know we have completed the wait, otherwise /* Let the signaler know we have completed the wait, otherwise
the signaler can race ahead and get the condition semaphore the signaler can race ahead and get the condition semaphore
@@ -223,10 +218,4 @@ int SDL_CondWaitTimeout_generic(SDL_cond *_cond, SDL_mutex *mutex, Uint32 ms)
return retval; return retval;
} }
/* Wait on the condition variable forever */
int SDL_CondWait_generic(SDL_cond *cond, SDL_mutex *mutex)
{
return SDL_CondWaitTimeout_generic(cond, mutex, SDL_MUTEX_MAXWAIT);
}
/* vi: set ts=4 sw=4 expandtab: */ /* vi: set ts=4 sw=4 expandtab: */
+1 -3
View File
@@ -29,9 +29,7 @@ SDL_cond *SDL_CreateCond_generic(void);
void SDL_DestroyCond_generic(SDL_cond *cond); void SDL_DestroyCond_generic(SDL_cond *cond);
int SDL_CondSignal_generic(SDL_cond *cond); int SDL_CondSignal_generic(SDL_cond *cond);
int SDL_CondBroadcast_generic(SDL_cond *cond); int SDL_CondBroadcast_generic(SDL_cond *cond);
int SDL_CondWait_generic(SDL_cond *cond, SDL_mutex *mutex); int SDL_CondWaitTimeoutNS_generic(SDL_cond *cond, SDL_mutex *mutex, Sint64 timeoutNS);
int SDL_CondWaitTimeout_generic(SDL_cond *cond,
SDL_mutex *mutex, Uint32 ms);
#endif /* SDL_THREAD_GENERIC_COND_SUFFIX */ #endif /* SDL_THREAD_GENERIC_COND_SUFFIX */
+15 -40
View File
@@ -37,17 +37,7 @@ void SDL_DestroySemaphore(SDL_sem *sem)
{ {
} }
int SDL_SemTryWait(SDL_sem *sem) int SDL_SemWaitTimeoutNS(SDL_sem *sem, Sint64 timeoutNS)
{
return SDL_SetError("SDL not built with thread support");
}
int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
{
return SDL_SetError("SDL not built with thread support");
}
int SDL_SemWait(SDL_sem *sem)
{ {
return SDL_SetError("SDL not built with thread support"); return SDL_SetError("SDL not built with thread support");
} }
@@ -117,26 +107,7 @@ void SDL_DestroySemaphore(SDL_sem *sem)
} }
} }
int SDL_SemTryWait(SDL_sem *sem) int SDL_SemWaitTimeoutNS(SDL_sem *sem, Sint64 timeoutNS)
{
int retval;
if (sem == NULL) {
return SDL_InvalidParamError("sem");
}
retval = SDL_MUTEX_TIMEDOUT;
SDL_LockMutex(sem->count_lock);
if (sem->count > 0) {
--sem->count;
retval = 0;
}
SDL_UnlockMutex(sem->count_lock);
return retval;
}
int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
{ {
int retval; int retval;
@@ -145,16 +116,24 @@ int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
} }
/* A timeout of 0 is an easy case */ /* A timeout of 0 is an easy case */
if (timeout == 0) { if (timeoutNS == 0) {
return SDL_SemTryWait(sem); retval = SDL_MUTEX_TIMEDOUT;
SDL_LockMutex(sem->count_lock);
if (sem->count > 0) {
--sem->count;
retval = 0;
}
SDL_UnlockMutex(sem->count_lock);
return retval;
} }
SDL_LockMutex(sem->count_lock); SDL_LockMutex(sem->count_lock);
++sem->waiters_count; ++sem->waiters_count;
retval = 0; retval = 0;
while ((sem->count == 0) && (retval != SDL_MUTEX_TIMEDOUT)) { while ((sem->count == 0) && (retval != SDL_MUTEX_TIMEDOUT)) {
retval = SDL_CondWaitTimeout(sem->count_nonzero, retval = SDL_CondWaitTimeoutNS(sem->count_nonzero,
sem->count_lock, timeout); sem->count_lock, timeoutNS);
} }
--sem->waiters_count; --sem->waiters_count;
if (retval == 0) { if (retval == 0) {
@@ -165,11 +144,6 @@ int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
return retval; return retval;
} }
int SDL_SemWait(SDL_sem *sem)
{
return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
}
Uint32 Uint32
SDL_SemValue(SDL_sem *sem) SDL_SemValue(SDL_sem *sem)
{ {
@@ -201,4 +175,5 @@ int SDL_SemPost(SDL_sem *sem)
} }
#endif /* SDL_THREADS_DISABLED */ #endif /* SDL_THREADS_DISABLED */
/* vi: set ts=4 sw=4 expandtab: */ /* vi: set ts=4 sw=4 expandtab: */
+4 -11
View File
@@ -74,7 +74,7 @@ int SDL_CondBroadcast(SDL_cond *cond)
return 0; return 0;
} }
/* Wait on the condition variable for at most 'ms' milliseconds. /* Wait on the condition variable for at most 'timeoutNS' nanoseconds.
The mutex must be locked before entering this function! The mutex must be locked before entering this function!
The mutex is unlocked during the wait, and locked again after the wait. The mutex is unlocked during the wait, and locked again after the wait.
@@ -95,7 +95,7 @@ Thread B:
SDL_CondSignal(cond); SDL_CondSignal(cond);
SDL_UnlockMutex(lock); SDL_UnlockMutex(lock);
*/ */
int SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms) int SDL_CondWaitTimeoutNS(SDL_cond *cond, SDL_mutex *mutex, Sint64 timeoutNS)
{ {
Result res; Result res;
@@ -107,22 +107,15 @@ int SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms)
} }
res = 0; res = 0;
if (ms == SDL_MUTEX_MAXWAIT) { if (timeoutNS < 0) {
CondVar_Wait(&cond->cond_variable, &mutex->lock.lock); CondVar_Wait(&cond->cond_variable, &mutex->lock.lock);
} else { } else {
res = CondVar_WaitTimeout(&cond->cond_variable, &mutex->lock.lock, res = CondVar_WaitTimeout(&cond->cond_variable, &mutex->lock.lock, timeoutNS);
(s64)ms * 1000000LL);
} }
return R_SUCCEEDED(res) ? 0 : SDL_MUTEX_TIMEDOUT; return R_SUCCEEDED(res) ? 0 : SDL_MUTEX_TIMEDOUT;
} }
/* Wait on the condition variable forever */
int SDL_CondWait(SDL_cond *cond, SDL_mutex *mutex)
{
return SDL_CondWaitTimeout(cond, mutex, SDL_MUTEX_MAXWAIT);
}
#endif /* SDL_THREAD_N3DS */ #endif /* SDL_THREAD_N3DS */
/* vi: set sts=4 ts=4 sw=4 expandtab: */ /* vi: set sts=4 ts=4 sw=4 expandtab: */
+5 -16
View File
@@ -62,16 +62,7 @@ void SDL_DestroySemaphore(SDL_sem *sem)
} }
} }
int SDL_SemTryWait(SDL_sem *sem) int SDL_SemWaitTimeoutNS(SDL_sem *sem, Sint64 timeoutNS)
{
if (sem == NULL) {
return SDL_InvalidParamError("sem");
}
return SDL_SemWaitTimeout(sem, 0);
}
int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
{ {
int retval; int retval;
@@ -79,12 +70,15 @@ int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
return SDL_InvalidParamError("sem"); return SDL_InvalidParamError("sem");
} }
if (timeout == SDL_MUTEX_MAXWAIT) { if (timeoutNS == SDL_MUTEX_MAXWAIT) {
LightSemaphore_Acquire(&sem->semaphore, 1); LightSemaphore_Acquire(&sem->semaphore, 1);
retval = 0; retval = 0;
} else { } else {
int return_code = LightSemaphore_TryAcquire(&sem->semaphore, 1); int return_code = LightSemaphore_TryAcquire(&sem->semaphore, 1);
if (return_code != 0) { if (return_code != 0) {
/* FIXME: Does this code guarantee a wall clock timeout here?
* Can we handle sub-millisecond delays? */
u32 timeout = (u32)SDL_NS_TO_MS(timeoutNS);
for (u32 i = 0; i < timeout; i++) { for (u32 i = 0; i < timeout; i++) {
svcSleepThread(1000000LL); svcSleepThread(1000000LL);
return_code = LightSemaphore_TryAcquire(&sem->semaphore, 1); return_code = LightSemaphore_TryAcquire(&sem->semaphore, 1);
@@ -99,11 +93,6 @@ int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
return retval; return retval;
} }
int SDL_SemWait(SDL_sem *sem)
{
return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
}
Uint32 Uint32
SDL_SemValue(SDL_sem *sem) SDL_SemValue(SDL_sem *sem)
{ {
+12 -21
View File
@@ -100,19 +100,27 @@ void SDL_DestroySemaphore(SDL_sem *sem)
} }
} }
int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout) int SDL_SemWaitTimeoutNS(SDL_sem *sem, Sint64 timeoutNS)
{ {
if (sem == NULL) { if (sem == NULL) {
return SDL_InvalidParamError("sem"); return SDL_InvalidParamError("sem");
} }
if (timeout == SDL_MUTEX_MAXWAIT) { if (timeoutNS == 0) {
if (sem->count > 0) {
--sem->count;
return 0;
}
return SDL_MUTEX_TIMEOUT;
}
if (timeoutNS == SDL_MUTEX_MAXWAIT) {
WaitAll(sem); WaitAll(sem);
return SDL_MUTEX_MAXWAIT; return 0;
} }
RThread thread; RThread thread;
TInfo *info = new (ELeave) TInfo(timeout, sem->handle); TInfo *info = new (ELeave) TInfo((TInt)SDL_NS_TO_MS(timeoutNS), sem->handle);
TInt status = CreateUnique(NewThread, &thread, info); TInt status = CreateUnique(NewThread, &thread, info);
if (status != KErrNone) { if (status != KErrNone) {
@@ -130,23 +138,6 @@ int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
return info->iVal; return info->iVal;
} }
int SDL_SemTryWait(SDL_sem *sem)
{
if (sem == NULL) {
return SDL_InvalidParamError("sem");
}
if (sem->count > 0) {
sem->count--;
}
return SDL_MUTEX_TIMEOUT;
}
int SDL_SemWait(SDL_sem *sem)
{
return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
}
Uint32 Uint32
SDL_SemValue(SDL_sem *sem) SDL_SemValue(SDL_sem *sem)
{ {
+4 -14
View File
@@ -79,7 +79,7 @@ void SDL_DestroySemaphore(SDL_sem *sem)
} }
} }
int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout) int SDL_SemWaitTimeoutNS(SDL_sem *sem, Sint64 timeoutNS)
{ {
int ret; int ret;
struct timer_alarm_t alarm; struct timer_alarm_t alarm;
@@ -89,15 +89,15 @@ int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
return SDL_InvalidParamError("sem"); return SDL_InvalidParamError("sem");
} }
if (timeout == 0) { if (timeoutNS == 0) {
if (PollSema(sem->semid) < 0) { if (PollSema(sem->semid) < 0) {
return SDL_MUTEX_TIMEDOUT; return SDL_MUTEX_TIMEDOUT;
} }
return 0; return 0;
} }
if (timeout != SDL_MUTEX_MAXWAIT) { if (timeoutNS != SDL_MUTEX_MAXWAIT) {
SetTimerAlarm(&alarm, MSec2TimerBusClock(timeout), &usercb, (void *)GetThreadId()); SetTimerAlarm(&alarm, MSec2TimerBusClock(SDL_NS_TO_MS(timeoutNS)), &usercb, (void *)GetThreadId());
} }
ret = WaitSema(sem->semid); ret = WaitSema(sem->semid);
@@ -109,16 +109,6 @@ int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
return 0; // Wait condition satisfied. return 0; // Wait condition satisfied.
} }
int SDL_SemTryWait(SDL_sem *sem)
{
return SDL_SemWaitTimeout(sem, 0);
}
int SDL_SemWait(SDL_sem *sem)
{
return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
}
/* Returns the current count of the semaphore */ /* Returns the current count of the semaphore */
Uint32 SDL_SemValue(SDL_sem *sem) Uint32 SDL_SemValue(SDL_sem *sem)
{ {
+3 -13
View File
@@ -132,7 +132,7 @@ int SDL_CondBroadcast(SDL_cond *cond)
return 0; return 0;
} }
/* Wait on the condition variable for at most 'ms' milliseconds. /* Wait on the condition variable for at most 'timeoutNS' nanoseconds.
The mutex must be locked before entering this function! The mutex must be locked before entering this function!
The mutex is unlocked during the wait, and locked again after the wait. The mutex is unlocked during the wait, and locked again after the wait.
@@ -153,7 +153,7 @@ Thread B:
SDL_CondSignal(cond); SDL_CondSignal(cond);
SDL_UnlockMutex(lock); SDL_UnlockMutex(lock);
*/ */
int SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms) int SDL_CondWaitTimeoutNS(SDL_cond *cond, SDL_mutex *mutex, Sint64 timeoutNS)
{ {
int retval; int retval;
@@ -173,11 +173,7 @@ int SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms)
SDL_UnlockMutex(mutex); SDL_UnlockMutex(mutex);
/* Wait for a signal */ /* Wait for a signal */
if (ms == SDL_MUTEX_MAXWAIT) { retval = SDL_SemWaitTimeout(cond->wait_sem, timeoutNS);
retval = SDL_SemWait(cond->wait_sem);
} else {
retval = SDL_SemWaitTimeout(cond->wait_sem, ms);
}
/* Let the signaler know we have completed the wait, otherwise /* Let the signaler know we have completed the wait, otherwise
the signaler can race ahead and get the condition semaphore the signaler can race ahead and get the condition semaphore
@@ -206,12 +202,6 @@ int SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms)
return retval; return retval;
} }
/* Wait on the condition variable forever */
int SDL_CondWait(SDL_cond *cond, SDL_mutex *mutex)
{
return SDL_CondWaitTimeout(cond, mutex, SDL_MUTEX_MAXWAIT);
}
#endif /* SDL_THREAD_PSP */ #endif /* SDL_THREAD_PSP */
/* vi: set ts=4 sw=4 expandtab: */ /* vi: set ts=4 sw=4 expandtab: */
+8 -17
View File
@@ -73,16 +73,17 @@ void SDL_DestroySemaphore(SDL_sem *sem)
* If the timeout is 0 then just poll the semaphore; if it's SDL_MUTEX_MAXWAIT, pass * If the timeout is 0 then just poll the semaphore; if it's SDL_MUTEX_MAXWAIT, pass
* NULL to sceKernelWaitSema() so that it waits indefinitely; and if the timeout * NULL to sceKernelWaitSema() so that it waits indefinitely; and if the timeout
* is specified, convert it to microseconds. */ * is specified, convert it to microseconds. */
int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout) int SDL_SemWaitTimeoutNS(SDL_sem *sem, Sint64 timeoutNS)
{ {
Uint32 *pTimeout; SceUInt timeoutUS;
SceUInt *pTimeout;
int res; int res;
if (sem == NULL) { if (sem == NULL) {
return SDL_InvalidParamError("sem"); return SDL_InvalidParamError("sem");
} }
if (timeout == 0) { if (timeoutNS == 0) {
res = sceKernelPollSema(sem->semid, 1); res = sceKernelPollSema(sem->semid, 1);
if (res < 0) { if (res < 0) {
return SDL_MUTEX_TIMEDOUT; return SDL_MUTEX_TIMEDOUT;
@@ -90,14 +91,14 @@ int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
return 0; return 0;
} }
if (timeout == SDL_MUTEX_MAXWAIT) { if (timeoutNS < 0) {
pTimeout = NULL; pTimeout = NULL;
} else { } else {
timeout *= 1000; /* Convert to microseconds. */ timeoutUS = (SceUInt)SDL_NS_TO_US(timeoutNS); /* Convert to microseconds. */
pTimeout = &timeout; pTimeout = &timeoutUS;
} }
res = sceKernelWaitSema(sem->semid, 1, (SceUInt *)pTimeout); res = sceKernelWaitSema(sem->semid, 1, pTimeout);
switch (res) { switch (res) {
case SCE_KERNEL_ERROR_OK: case SCE_KERNEL_ERROR_OK:
return 0; return 0;
@@ -108,16 +109,6 @@ int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
} }
} }
int SDL_SemTryWait(SDL_sem *sem)
{
return SDL_SemWaitTimeout(sem, 0);
}
int SDL_SemWait(SDL_sem *sem)
{
return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
}
/* Returns the current count of the semaphore */ /* Returns the current count of the semaphore */
Uint32 SDL_SemValue(SDL_sem *sem) Uint32 SDL_SemValue(SDL_sem *sem)
{ {
+13 -19
View File
@@ -91,7 +91,7 @@ int SDL_CondBroadcast(SDL_cond *cond)
return retval; return retval;
} }
int SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms) int SDL_CondWaitTimeoutNS(SDL_cond *cond, SDL_mutex *mutex, Sint64 timeoutNS)
{ {
int retval; int retval;
#ifndef HAVE_CLOCK_GETTIME #ifndef HAVE_CLOCK_GETTIME
@@ -103,18 +103,25 @@ int SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms)
return SDL_InvalidParamError("cond"); return SDL_InvalidParamError("cond");
} }
if (timeoutNS < 0) {
if (pthread_cond_wait(&cond->cond, &mutex->id) != 0) {
return SDL_SetError("pthread_cond_wait() failed");
}
return 0;
}
#ifdef HAVE_CLOCK_GETTIME #ifdef HAVE_CLOCK_GETTIME
clock_gettime(CLOCK_REALTIME, &abstime); clock_gettime(CLOCK_REALTIME, &abstime);
abstime.tv_nsec += (ms % 1000) * 1000000; abstime.tv_sec += (timeoutNS / SDL_NS_PER_SECOND);
abstime.tv_sec += ms / 1000; abstime.tv_nsec += (timeoutNS % SDL_NS_PER_SECOND);
#else #else
gettimeofday(&delta, NULL); gettimeofday(&delta, NULL);
abstime.tv_sec = delta.tv_sec + (ms / 1000); abstime.tv_sec = delta.tv_sec + (timeoutNS / SDL_NS_PER_SECOND);
abstime.tv_nsec = (long)(delta.tv_usec + (ms % 1000) * 1000) * 1000; abstime.tv_nsec = SDL_US_TO_NS(delta.tv_usec) + (timeoutNS % SDL_NS_PER_SECOND);
#endif #endif
if (abstime.tv_nsec > 1000000000) { while (abstime.tv_nsec > 1000000000) {
abstime.tv_sec += 1; abstime.tv_sec += 1;
abstime.tv_nsec -= 1000000000; abstime.tv_nsec -= 1000000000;
} }
@@ -136,17 +143,4 @@ tryagain:
return retval; return retval;
} }
/* Wait on the condition variable, unlocking the provided mutex.
The mutex must be locked before entering this function!
*/
int SDL_CondWait(SDL_cond *cond, SDL_mutex *mutex)
{
if (cond == NULL) {
return SDL_InvalidParamError("cond");
} else if (pthread_cond_wait(&cond->cond, &mutex->id) != 0) {
return SDL_SetError("pthread_cond_wait() failed");
}
return 0;
}
/* vi: set ts=4 sw=4 expandtab: */ /* vi: set ts=4 sw=4 expandtab: */
+27 -47
View File
@@ -63,39 +63,7 @@ void SDL_DestroySemaphore(SDL_sem *sem)
} }
} }
int SDL_SemTryWait(SDL_sem *sem) int SDL_SemWaitTimeoutNS(SDL_sem *sem, Sint64 timeoutNS)
{
int retval;
if (sem == NULL) {
return SDL_InvalidParamError("sem");
}
retval = SDL_MUTEX_TIMEDOUT;
if (sem_trywait(&sem->sem) == 0) {
retval = 0;
}
return retval;
}
int SDL_SemWait(SDL_sem *sem)
{
int retval;
if (sem == NULL) {
return SDL_InvalidParamError("sem");
}
do {
retval = sem_wait(&sem->sem);
} while (retval < 0 && errno == EINTR);
if (retval < 0) {
retval = SDL_SetError("sem_wait() failed");
}
return retval;
}
int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
{ {
int retval; int retval;
#ifdef HAVE_SEM_TIMEDWAIT #ifdef HAVE_SEM_TIMEDWAIT
@@ -104,7 +72,7 @@ int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
#endif #endif
struct timespec ts_timeout; struct timespec ts_timeout;
#else #else
Uint32 end; Uint64 end;
#endif #endif
if (sem == NULL) { if (sem == NULL) {
@@ -112,11 +80,22 @@ int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
} }
/* Try the easy cases first */ /* Try the easy cases first */
if (timeout == 0) { if (timeoutNS == 0) {
return SDL_SemTryWait(sem); retval = SDL_MUTEX_TIMEDOUT;
if (sem_trywait(&sem->sem) == 0) {
retval = 0;
}
return retval;
} }
if (timeout == SDL_MUTEX_MAXWAIT) { if (timeoutNS < 0) {
return SDL_SemWait(sem); do {
retval = sem_wait(&sem->sem);
} while (retval < 0 && errno == EINTR);
if (retval < 0) {
retval = SDL_SetError("sem_wait() failed");
}
return retval;
} }
#ifdef HAVE_SEM_TIMEDWAIT #ifdef HAVE_SEM_TIMEDWAIT
@@ -128,18 +107,18 @@ int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
clock_gettime(CLOCK_REALTIME, &ts_timeout); clock_gettime(CLOCK_REALTIME, &ts_timeout);
/* Add our timeout to current time */ /* Add our timeout to current time */
ts_timeout.tv_nsec += (timeout % 1000) * 1000000; ts_timeout.tv_sec += (timeoutNS / SDL_NS_PER_SECOND);
ts_timeout.tv_sec += timeout / 1000; ts_timeout.tv_nsec += (timeoutNS % SDL_NS_PER_SECOND);
#else #else
gettimeofday(&now, NULL); gettimeofday(&now, NULL);
/* Add our timeout to current time */ /* Add our timeout to current time */
ts_timeout.tv_sec = now.tv_sec + (timeout / 1000); ts_timeout.tv_sec = now.tv_sec + (timeoutNS / SDL_NS_PER_SECOND);
ts_timeout.tv_nsec = (now.tv_usec + (timeout % 1000) * 1000) * 1000; ts_timeout.tv_nsec = SDL_US_TO_NS(now.tv_usec) + (timeoutNS % SDL_NS_PER_SECOND);
#endif #endif
/* Wrap the second if needed */ /* Wrap the second if needed */
if (ts_timeout.tv_nsec > 1000000000) { while (ts_timeout.tv_nsec > 1000000000) {
ts_timeout.tv_sec += 1; ts_timeout.tv_sec += 1;
ts_timeout.tv_nsec -= 1000000000; ts_timeout.tv_nsec -= 1000000000;
} }
@@ -157,12 +136,13 @@ int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
} }
} }
#else #else
end = SDL_GetTicks() + timeout; end = SDL_GetTicksNS() + timeoutNS;
while ((retval = SDL_SemTryWait(sem)) == SDL_MUTEX_TIMEDOUT) { while (sem_trywait(&sem->sem) != 0) {
if (SDL_TICKS_PASSED(SDL_GetTicks(), end)) { if (SDL_GetTicksNS() >= end) {
retval = SDL_MUTEX_TIMEDOUT;
break; break;
} }
SDL_Delay(1); SDL_DelayNS(100);
} }
#endif /* HAVE_SEM_TIMEDWAIT */ #endif /* HAVE_SEM_TIMEDWAIT */
+5 -12
View File
@@ -85,7 +85,7 @@ SDL_CondBroadcast(SDL_cond *cond)
return 0; return 0;
} }
/* Wait on the condition variable for at most 'ms' milliseconds. /* Wait on the condition variable for at most 'timeoutNS' nanoseconds.
The mutex must be locked before entering this function! The mutex must be locked before entering this function!
The mutex is unlocked during the wait, and locked again after the wait. The mutex is unlocked during the wait, and locked again after the wait.
@@ -107,7 +107,7 @@ Thread B:
SDL_UnlockMutex(lock); SDL_UnlockMutex(lock);
*/ */
extern "C" int extern "C" int
SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms) SDL_CondWaitTimeoutNS(SDL_cond *cond, SDL_mutex *mutex, Sint64 timeoutNS)
{ {
if (cond == NULL) { if (cond == NULL) {
return SDL_InvalidParamError("cond"); return SDL_InvalidParamError("cond");
@@ -119,7 +119,7 @@ SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms)
try { try {
std::unique_lock<std::recursive_mutex> cpp_lock(mutex->cpp_mutex, std::adopt_lock_t()); std::unique_lock<std::recursive_mutex> cpp_lock(mutex->cpp_mutex, std::adopt_lock_t());
if (ms == SDL_MUTEX_MAXWAIT) { if (timeoutNS < 0) {
cond->cpp_cond.wait( cond->cpp_cond.wait(
cpp_lock); cpp_lock);
cpp_lock.release(); cpp_lock.release();
@@ -127,7 +127,7 @@ SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms)
} else { } else {
auto wait_result = cond->cpp_cond.wait_for( auto wait_result = cond->cpp_cond.wait_for(
cpp_lock, cpp_lock,
std::chrono::duration<Uint32, std::milli>(ms)); std::chrono::duration<Sint64, std::nano>(timeoutNS));
cpp_lock.release(); cpp_lock.release();
if (wait_result == std::cv_status::timeout) { if (wait_result == std::cv_status::timeout) {
return SDL_MUTEX_TIMEDOUT; return SDL_MUTEX_TIMEDOUT;
@@ -136,15 +136,8 @@ SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms)
} }
} }
} catch (std::system_error &ex) { } catch (std::system_error &ex) {
return SDL_SetError("unable to wait on a C++ condition variable: code=%d; %s", ex.code(), ex.what()); return SDL_SetError("Unable to wait on a C++ condition variable: code=%d; %s", ex.code(), ex.what());
} }
} }
/* Wait on the condition variable forever */
extern "C" int
SDL_CondWait(SDL_cond *cond, SDL_mutex *mutex)
{
return SDL_CondWaitTimeout(cond, mutex, SDL_MUTEX_MAXWAIT);
}
/* vi: set ts=4 sw=4 expandtab: */ /* vi: set ts=4 sw=4 expandtab: */
+3 -13
View File
@@ -132,7 +132,7 @@ int SDL_CondBroadcast(SDL_cond *cond)
return 0; return 0;
} }
/* Wait on the condition variable for at most 'ms' milliseconds. /* Wait on the condition variable for at most 'timeoutNS' nanoseconds.
The mutex must be locked before entering this function! The mutex must be locked before entering this function!
The mutex is unlocked during the wait, and locked again after the wait. The mutex is unlocked during the wait, and locked again after the wait.
@@ -153,7 +153,7 @@ Thread B:
SDL_CondSignal(cond); SDL_CondSignal(cond);
SDL_UnlockMutex(lock); SDL_UnlockMutex(lock);
*/ */
int SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms) int SDL_CondWaitTimeoutNS(SDL_cond *cond, SDL_mutex *mutex, Sint64 timeoutNS)
{ {
int retval; int retval;
@@ -173,11 +173,7 @@ int SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms)
SDL_UnlockMutex(mutex); SDL_UnlockMutex(mutex);
/* Wait for a signal */ /* Wait for a signal */
if (ms == SDL_MUTEX_MAXWAIT) { retval = SDL_SemWaitTimeoutNS(cond->wait_sem, timeoutNS);
retval = SDL_SemWait(cond->wait_sem);
} else {
retval = SDL_SemWaitTimeout(cond->wait_sem, ms);
}
/* Let the signaler know we have completed the wait, otherwise /* Let the signaler know we have completed the wait, otherwise
the signaler can race ahead and get the condition semaphore the signaler can race ahead and get the condition semaphore
@@ -206,12 +202,6 @@ int SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms)
return retval; return retval;
} }
/* Wait on the condition variable forever */
int SDL_CondWait(SDL_cond *cond, SDL_mutex *mutex)
{
return SDL_CondWaitTimeout(cond, mutex, SDL_MUTEX_MAXWAIT);
}
#endif /* SDL_THREAD_VITA */ #endif /* SDL_THREAD_VITA */
/* vi: set ts=4 sw=4 expandtab: */ /* vi: set ts=4 sw=4 expandtab: */
+8 -17
View File
@@ -74,16 +74,17 @@ void SDL_DestroySemaphore(SDL_sem *sem)
* If the timeout is 0 then just poll the semaphore; if it's SDL_MUTEX_MAXWAIT, pass * If the timeout is 0 then just poll the semaphore; if it's SDL_MUTEX_MAXWAIT, pass
* NULL to sceKernelWaitSema() so that it waits indefinitely; and if the timeout * NULL to sceKernelWaitSema() so that it waits indefinitely; and if the timeout
* is specified, convert it to microseconds. */ * is specified, convert it to microseconds. */
int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout) int SDL_SemWaitTimeoutNS(SDL_sem *sem, Sint64 timeoutNS)
{ {
Uint32 *pTimeout; SceUInt timeoutUS;
SceUInt *pTimeout;
int res; int res;
if (sem == NULL) { if (sem == NULL) {
return SDL_InvalidParamError("sem"); return SDL_InvalidParamError("sem");
} }
if (timeout == 0) { if (timeoutNS == 0) {
res = sceKernelPollSema(sem->semid, 1); res = sceKernelPollSema(sem->semid, 1);
if (res < 0) { if (res < 0) {
return SDL_MUTEX_TIMEDOUT; return SDL_MUTEX_TIMEDOUT;
@@ -91,11 +92,11 @@ int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
return 0; return 0;
} }
if (timeout == SDL_MUTEX_MAXWAIT) { if (timeoutNS < 0) {
pTimeout = NULL; pTimeout = NULL;
} else { } else {
timeout *= 1000; /* Convert to microseconds. */ timeoutUS = (SceUInt)SDL_NS_TO_US(timeoutNS); /* Convert to microseconds. */
pTimeout = &timeout; pTimeout = &timeoutUS;
} }
res = sceKernelWaitSema(sem->semid, 1, pTimeout); res = sceKernelWaitSema(sem->semid, 1, pTimeout);
@@ -105,20 +106,10 @@ int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
case SCE_KERNEL_ERROR_WAIT_TIMEOUT: case SCE_KERNEL_ERROR_WAIT_TIMEOUT:
return SDL_MUTEX_TIMEDOUT; return SDL_MUTEX_TIMEDOUT;
default: default:
return SDL_SetError("WaitForSingleObject() failed"); return SDL_SetError("sceKernelWaitSema() failed");
} }
} }
int SDL_SemTryWait(SDL_sem *sem)
{
return SDL_SemWaitTimeout(sem, 0);
}
int SDL_SemWait(SDL_sem *sem)
{
return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
}
/* Returns the current count of the semaphore */ /* Returns the current count of the semaphore */
Uint32 SDL_SemValue(SDL_sem *sem) Uint32 SDL_SemValue(SDL_sem *sem)
{ {
+9 -23
View File
@@ -27,8 +27,7 @@ typedef SDL_cond *(*pfnSDL_CreateCond)(void);
typedef void (*pfnSDL_DestroyCond)(SDL_cond *); typedef void (*pfnSDL_DestroyCond)(SDL_cond *);
typedef int (*pfnSDL_CondSignal)(SDL_cond *); typedef int (*pfnSDL_CondSignal)(SDL_cond *);
typedef int (*pfnSDL_CondBroadcast)(SDL_cond *); typedef int (*pfnSDL_CondBroadcast)(SDL_cond *);
typedef int (*pfnSDL_CondWait)(SDL_cond *, SDL_mutex *); typedef int (*pfnSDL_CondWaitTimeoutNS)(SDL_cond *, SDL_mutex *, Sint64);
typedef int (*pfnSDL_CondWaitTimeout)(SDL_cond *, SDL_mutex *, Uint32);
typedef struct SDL_cond_impl_t typedef struct SDL_cond_impl_t
{ {
@@ -36,8 +35,7 @@ typedef struct SDL_cond_impl_t
pfnSDL_DestroyCond Destroy; pfnSDL_DestroyCond Destroy;
pfnSDL_CondSignal Signal; pfnSDL_CondSignal Signal;
pfnSDL_CondBroadcast Broadcast; pfnSDL_CondBroadcast Broadcast;
pfnSDL_CondWait Wait; pfnSDL_CondWaitTimeoutNS WaitTimeoutNS;
pfnSDL_CondWaitTimeout WaitTimeout;
} SDL_cond_impl_t; } SDL_cond_impl_t;
/* Implementation will be chosen at runtime based on available Kernel features */ /* Implementation will be chosen at runtime based on available Kernel features */
@@ -125,7 +123,7 @@ static int SDL_CondBroadcast_cv(SDL_cond *_cond)
return 0; return 0;
} }
static int SDL_CondWaitTimeout_cv(SDL_cond *_cond, SDL_mutex *_mutex, Uint32 ms) static int SDL_CondWaitTimeoutNS_cv(SDL_cond *_cond, SDL_mutex *_mutex, Sint64 timeoutNS)
{ {
SDL_cond_cv *cond = (SDL_cond_cv *)_cond; SDL_cond_cv *cond = (SDL_cond_cv *)_cond;
DWORD timeout; DWORD timeout;
@@ -138,10 +136,10 @@ static int SDL_CondWaitTimeout_cv(SDL_cond *_cond, SDL_mutex *_mutex, Uint32 ms)
return SDL_InvalidParamError("mutex"); return SDL_InvalidParamError("mutex");
} }
if (ms == SDL_MUTEX_MAXWAIT) { if (timeoutNS < 0) {
timeout = INFINITE; timeout = INFINITE;
} else { } else {
timeout = (DWORD)ms; timeout = (DWORD)SDL_NS_TO_MS(timeoutNS);
} }
if (SDL_mutex_impl_active.Type == SDL_MUTEX_SRW) { if (SDL_mutex_impl_active.Type == SDL_MUTEX_SRW) {
@@ -188,18 +186,12 @@ static int SDL_CondWaitTimeout_cv(SDL_cond *_cond, SDL_mutex *_mutex, Uint32 ms)
return ret; return ret;
} }
static int SDL_CondWait_cv(SDL_cond *cond, SDL_mutex *mutex)
{
return SDL_CondWaitTimeout_cv(cond, mutex, SDL_MUTEX_MAXWAIT);
}
static const SDL_cond_impl_t SDL_cond_impl_cv = { static const SDL_cond_impl_t SDL_cond_impl_cv = {
&SDL_CreateCond_cv, &SDL_CreateCond_cv,
&SDL_DestroyCond_cv, &SDL_DestroyCond_cv,
&SDL_CondSignal_cv, &SDL_CondSignal_cv,
&SDL_CondBroadcast_cv, &SDL_CondBroadcast_cv,
&SDL_CondWait_cv, &SDL_CondWaitTimeoutNS_cv,
&SDL_CondWaitTimeout_cv,
}; };
/** /**
@@ -211,8 +203,7 @@ static const SDL_cond_impl_t SDL_cond_impl_generic = {
&SDL_DestroyCond_generic, &SDL_DestroyCond_generic,
&SDL_CondSignal_generic, &SDL_CondSignal_generic,
&SDL_CondBroadcast_generic, &SDL_CondBroadcast_generic,
&SDL_CondWait_generic, &SDL_CondWaitTimeoutNS_generic,
&SDL_CondWaitTimeout_generic,
}; };
SDL_cond * SDL_cond *
@@ -272,14 +263,9 @@ int SDL_CondBroadcast(SDL_cond *cond)
return SDL_cond_impl_active.Broadcast(cond); return SDL_cond_impl_active.Broadcast(cond);
} }
int SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms) int SDL_CondWaitTimeoutNS(SDL_cond *cond, SDL_mutex *mutex, Sint64 timeoutNS)
{ {
return SDL_cond_impl_active.WaitTimeout(cond, mutex, ms); return SDL_cond_impl_active.WaitTimeoutNS(cond, mutex, timeoutNS);
}
int SDL_CondWait(SDL_cond *cond, SDL_mutex *mutex)
{
return SDL_cond_impl_active.Wait(cond, mutex);
} }
/* vi: set ts=4 sw=4 expandtab: */ /* vi: set ts=4 sw=4 expandtab: */
+35 -84
View File
@@ -37,9 +37,7 @@
typedef SDL_sem *(*pfnSDL_CreateSemaphore)(Uint32); typedef SDL_sem *(*pfnSDL_CreateSemaphore)(Uint32);
typedef void (*pfnSDL_DestroySemaphore)(SDL_sem *); typedef void (*pfnSDL_DestroySemaphore)(SDL_sem *);
typedef int (*pfnSDL_SemWaitTimeout)(SDL_sem *, Uint32); typedef int (*pfnSDL_SemWaitTimeoutNS)(SDL_sem *, Sint64);
typedef int (*pfnSDL_SemTryWait)(SDL_sem *);
typedef int (*pfnSDL_SemWait)(SDL_sem *);
typedef Uint32 (*pfnSDL_SemValue)(SDL_sem *); typedef Uint32 (*pfnSDL_SemValue)(SDL_sem *);
typedef int (*pfnSDL_SemPost)(SDL_sem *); typedef int (*pfnSDL_SemPost)(SDL_sem *);
@@ -47,9 +45,7 @@ typedef struct SDL_semaphore_impl_t
{ {
pfnSDL_CreateSemaphore Create; pfnSDL_CreateSemaphore Create;
pfnSDL_DestroySemaphore Destroy; pfnSDL_DestroySemaphore Destroy;
pfnSDL_SemWaitTimeout WaitTimeout; pfnSDL_SemWaitTimeoutNS WaitTimeoutNS;
pfnSDL_SemTryWait TryWait;
pfnSDL_SemWait Wait;
pfnSDL_SemValue Value; pfnSDL_SemValue Value;
pfnSDL_SemPost Post; pfnSDL_SemPost Post;
} SDL_sem_impl_t; } SDL_sem_impl_t;
@@ -108,81 +104,60 @@ static void SDL_DestroySemaphore_atom(SDL_sem *sem)
} }
} }
static int SDL_SemTryWait_atom(SDL_sem *_sem) static int SDL_SemWaitTimeoutNS_atom(SDL_sem *_sem, Sint64 timeoutNS)
{ {
SDL_sem_atom *sem = (SDL_sem_atom *)_sem; SDL_sem_atom *sem = (SDL_sem_atom *)_sem;
LONG count; LONG count;
Uint64 now;
Uint64 deadline;
DWORD timeout_eff;
if (sem == NULL) { if (sem == NULL) {
return SDL_InvalidParamError("sem"); return SDL_InvalidParamError("sem");
} }
count = sem->count; if (timeoutNS == 0) {
if (count == 0) {
return SDL_MUTEX_TIMEDOUT;
}
if (InterlockedCompareExchange(&sem->count, count - 1, count) == count) {
return 0;
}
return SDL_MUTEX_TIMEDOUT;
}
static int SDL_SemWait_atom(SDL_sem *_sem)
{
SDL_sem_atom *sem = (SDL_sem_atom *)_sem;
LONG count;
if (sem == NULL) {
return SDL_InvalidParamError("sem");
}
for (;;) {
count = sem->count; count = sem->count;
while (count == 0) { if (count == 0) {
if (pWaitOnAddress(&sem->count, &count, sizeof(sem->count), INFINITE) == FALSE) { return SDL_MUTEX_TIMEDOUT;
return SDL_SetError("WaitOnAddress() failed");
}
count = sem->count;
} }
if (InterlockedCompareExchange(&sem->count, count - 1, count) == count) { if (InterlockedCompareExchange(&sem->count, count - 1, count) == count) {
return 0; return 0;
} }
return SDL_MUTEX_TIMEDOUT;
} }
} if (timeoutNS < 0) {
for (;;) {
count = sem->count;
while (count == 0) {
if (pWaitOnAddress(&sem->count, &count, sizeof(sem->count), INFINITE) == FALSE) {
return SDL_SetError("WaitOnAddress() failed");
}
count = sem->count;
}
static int SDL_SemWaitTimeout_atom(SDL_sem *_sem, Uint32 timeout) if (InterlockedCompareExchange(&sem->count, count - 1, count) == count) {
{ return 0;
SDL_sem_atom *sem = (SDL_sem_atom *)_sem; }
LONG count; }
Uint32 now;
Uint32 deadline;
DWORD timeout_eff;
if (timeout == SDL_MUTEX_MAXWAIT) {
return SDL_SemWait_atom(_sem);
}
if (sem == NULL) {
return SDL_InvalidParamError("sem");
} }
/** /**
* WaitOnAddress is subject to spurious and stolen wakeups so we * WaitOnAddress is subject to spurious and stolen wakeups so we
* need to recalculate the effective timeout before every wait * need to recalculate the effective timeout before every wait
*/ */
now = SDL_GetTicks(); now = SDL_GetTicksNS();
deadline = now + (DWORD)timeout; deadline = now + timeoutNS;
for (;;) { for (;;) {
count = sem->count; count = sem->count;
/* If no semaphore is available we need to wait */ /* If no semaphore is available we need to wait */
while (count == 0) { while (count == 0) {
now = SDL_GetTicks(); now = SDL_GetTicksNS();
if (deadline > now) { if (deadline > now) {
timeout_eff = deadline - now; timeout_eff = (DWORD)SDL_NS_TO_MS(deadline - now);
} else { } else {
return SDL_MUTEX_TIMEDOUT; return SDL_MUTEX_TIMEDOUT;
} }
@@ -232,9 +207,7 @@ static int SDL_SemPost_atom(SDL_sem *_sem)
static const SDL_sem_impl_t SDL_sem_impl_atom = { static const SDL_sem_impl_t SDL_sem_impl_atom = {
&SDL_CreateSemaphore_atom, &SDL_CreateSemaphore_atom,
&SDL_DestroySemaphore_atom, &SDL_DestroySemaphore_atom,
&SDL_SemWaitTimeout_atom, &SDL_SemWaitTimeoutNS_atom,
&SDL_SemTryWait_atom,
&SDL_SemWait_atom,
&SDL_SemValue_atom, &SDL_SemValue_atom,
&SDL_SemPost_atom, &SDL_SemPost_atom,
}; };
@@ -289,7 +262,7 @@ static void SDL_DestroySemaphore_kern(SDL_sem *_sem)
} }
} }
static int SDL_SemWaitTimeout_kern(SDL_sem *_sem, Uint32 timeout) static int SDL_SemWaitTimeoutNS_kern(SDL_sem *_sem, Sint64 timeoutNS)
{ {
SDL_sem_kern *sem = (SDL_sem_kern *)_sem; SDL_sem_kern *sem = (SDL_sem_kern *)_sem;
int retval; int retval;
@@ -299,10 +272,10 @@ static int SDL_SemWaitTimeout_kern(SDL_sem *_sem, Uint32 timeout)
return SDL_InvalidParamError("sem"); return SDL_InvalidParamError("sem");
} }
if (timeout == SDL_MUTEX_MAXWAIT) { if (timeoutNS < 0) {
dwMilliseconds = INFINITE; dwMilliseconds = INFINITE;
} else { } else {
dwMilliseconds = (DWORD)timeout; dwMilliseconds = (DWORD)SDL_NS_TO_MS(timeoutNS);
} }
switch (WaitForSingleObjectEx(sem->id, dwMilliseconds, FALSE)) { switch (WaitForSingleObjectEx(sem->id, dwMilliseconds, FALSE)) {
case WAIT_OBJECT_0: case WAIT_OBJECT_0:
@@ -319,16 +292,6 @@ static int SDL_SemWaitTimeout_kern(SDL_sem *_sem, Uint32 timeout)
return retval; return retval;
} }
static int SDL_SemTryWait_kern(SDL_sem *sem)
{
return SDL_SemWaitTimeout_kern(sem, 0);
}
static int SDL_SemWait_kern(SDL_sem *sem)
{
return SDL_SemWaitTimeout_kern(sem, SDL_MUTEX_MAXWAIT);
}
/* Returns the current count of the semaphore */ /* Returns the current count of the semaphore */
static Uint32 SDL_SemValue_kern(SDL_sem *_sem) static Uint32 SDL_SemValue_kern(SDL_sem *_sem)
{ {
@@ -362,9 +325,7 @@ static int SDL_SemPost_kern(SDL_sem *_sem)
static const SDL_sem_impl_t SDL_sem_impl_kern = { static const SDL_sem_impl_t SDL_sem_impl_kern = {
&SDL_CreateSemaphore_kern, &SDL_CreateSemaphore_kern,
&SDL_DestroySemaphore_kern, &SDL_DestroySemaphore_kern,
&SDL_SemWaitTimeout_kern, &SDL_SemWaitTimeoutNS_kern,
&SDL_SemTryWait_kern,
&SDL_SemWait_kern,
&SDL_SemValue_kern, &SDL_SemValue_kern,
&SDL_SemPost_kern, &SDL_SemPost_kern,
}; };
@@ -417,19 +378,9 @@ void SDL_DestroySemaphore(SDL_sem *sem)
SDL_sem_impl_active.Destroy(sem); SDL_sem_impl_active.Destroy(sem);
} }
int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout) int SDL_SemWaitTimeoutNS(SDL_sem *sem, Sint64 timeoutNS)
{ {
return SDL_sem_impl_active.WaitTimeout(sem, timeout); return SDL_sem_impl_active.WaitTimeoutNS(sem, timeoutNS);
}
int SDL_SemTryWait(SDL_sem *sem)
{
return SDL_sem_impl_active.TryWait(sem);
}
int SDL_SemWait(SDL_sem *sem)
{
return SDL_sem_impl_active.Wait(sem);
} }
Uint32 Uint32
+101 -26
View File
@@ -32,8 +32,8 @@ typedef struct _SDL_Timer
int timerID; int timerID;
SDL_TimerCallback callback; SDL_TimerCallback callback;
void *param; void *param;
Uint32 interval; Uint64 interval;
Uint32 scheduled; Uint64 scheduled;
SDL_atomic_t canceled; SDL_atomic_t canceled;
struct _SDL_Timer *next; struct _SDL_Timer *next;
} SDL_Timer; } SDL_Timer;
@@ -82,7 +82,7 @@ static void SDL_AddTimerInternal(SDL_TimerData *data, SDL_Timer *timer)
prev = NULL; prev = NULL;
for (curr = data->timers; curr; prev = curr, curr = curr->next) { for (curr = data->timers; curr; prev = curr, curr = curr->next) {
if ((Sint32)(timer->scheduled - curr->scheduled) < 0) { if (curr->scheduled > timer->scheduled) {
break; break;
} }
} }
@@ -103,7 +103,7 @@ static int SDLCALL SDL_TimerThread(void *_data)
SDL_Timer *current; SDL_Timer *current;
SDL_Timer *freelist_head = NULL; SDL_Timer *freelist_head = NULL;
SDL_Timer *freelist_tail = NULL; SDL_Timer *freelist_tail = NULL;
Uint32 tick, now, interval, delay; Uint64 tick, now, interval, delay;
/* Threaded timer loop: /* Threaded timer loop:
* 1. Queue timers added by other threads * 1. Queue timers added by other threads
@@ -143,13 +143,13 @@ static int SDLCALL SDL_TimerThread(void *_data)
/* Initial delay if there are no timers */ /* Initial delay if there are no timers */
delay = SDL_MUTEX_MAXWAIT; delay = SDL_MUTEX_MAXWAIT;
tick = SDL_GetTicks(); tick = SDL_GetTicksNS();
/* Process all the pending timers for this tick */ /* Process all the pending timers for this tick */
while (data->timers) { while (data->timers) {
current = data->timers; current = data->timers;
if ((Sint32)(tick - current->scheduled) < 0) { if (tick < current->scheduled) {
/* Scheduled for the future, wait a bit */ /* Scheduled for the future, wait a bit */
delay = (current->scheduled - tick); delay = (current->scheduled - tick);
break; break;
@@ -161,7 +161,8 @@ static int SDLCALL SDL_TimerThread(void *_data)
if (SDL_AtomicGet(&current->canceled)) { if (SDL_AtomicGet(&current->canceled)) {
interval = 0; interval = 0;
} else { } else {
interval = current->callback(current->interval, current->param); /* FIXME: We could potentially support sub-millisecond timers now */
interval = SDL_MS_TO_NS(current->callback((Uint32)SDL_NS_TO_MS(current->interval), current->param));
} }
if (interval > 0) { if (interval > 0) {
@@ -183,7 +184,7 @@ static int SDLCALL SDL_TimerThread(void *_data)
} }
/* Adjust the delay based on processing time */ /* Adjust the delay based on processing time */
now = SDL_GetTicks(); now = SDL_GetTicksNS();
interval = (now - tick); interval = (now - tick);
if (interval > delay) { if (interval > delay) {
delay = 0; delay = 0;
@@ -196,7 +197,7 @@ static int SDLCALL SDL_TimerThread(void *_data)
That's okay, it just means we run through the loop a few That's okay, it just means we run through the loop a few
extra times. extra times.
*/ */
SDL_SemWaitTimeout(data->sem, delay); SDL_SemWaitTimeoutNS(data->sem, delay);
} }
return 0; return 0;
} }
@@ -271,8 +272,7 @@ void SDL_TimerQuit(void)
} }
} }
SDL_TimerID SDL_TimerID SDL_AddTimer(Uint32 interval, SDL_TimerCallback callback, void *param)
SDL_AddTimer(Uint32 interval, SDL_TimerCallback callback, void *param)
{ {
SDL_TimerData *data = &SDL_timer_data; SDL_TimerData *data = &SDL_timer_data;
SDL_Timer *timer; SDL_Timer *timer;
@@ -304,8 +304,8 @@ SDL_AddTimer(Uint32 interval, SDL_TimerCallback callback, void *param)
timer->timerID = SDL_AtomicIncRef(&data->nextID); timer->timerID = SDL_AtomicIncRef(&data->nextID);
timer->callback = callback; timer->callback = callback;
timer->param = param; timer->param = param;
timer->interval = interval; timer->interval = SDL_MS_TO_NS(interval);
timer->scheduled = SDL_GetTicks() + interval; timer->scheduled = SDL_GetTicksNS() + timer->interval;
SDL_AtomicSet(&timer->canceled, 0); SDL_AtomicSet(&timer->canceled, 0);
entry = (SDL_TimerMap *)SDL_malloc(sizeof(*entry)); entry = (SDL_TimerMap *)SDL_malloc(sizeof(*entry));
@@ -334,8 +334,7 @@ SDL_AddTimer(Uint32 interval, SDL_TimerCallback callback, void *param)
return entry->timerID; return entry->timerID;
} }
SDL_bool SDL_bool SDL_RemoveTimer(SDL_TimerID id)
SDL_RemoveTimer(SDL_TimerID id)
{ {
SDL_TimerData *data = &SDL_timer_data; SDL_TimerData *data = &SDL_timer_data;
SDL_TimerMap *prev, *entry; SDL_TimerMap *prev, *entry;
@@ -417,8 +416,7 @@ void SDL_TimerQuit(void)
} }
} }
SDL_TimerID SDL_TimerID SDL_AddTimer(Uint32 interval, SDL_TimerCallback callback, void *param)
SDL_AddTimer(Uint32 interval, SDL_TimerCallback callback, void *param)
{ {
SDL_TimerData *data = &SDL_timer_data; SDL_TimerData *data = &SDL_timer_data;
SDL_TimerMap *entry; SDL_TimerMap *entry;
@@ -443,8 +441,7 @@ SDL_AddTimer(Uint32 interval, SDL_TimerCallback callback, void *param)
return entry->timerID; return entry->timerID;
} }
SDL_bool SDL_bool SDL_RemoveTimer(SDL_TimerID id)
SDL_RemoveTimer(SDL_TimerID id)
{ {
SDL_TimerData *data = &SDL_timer_data; SDL_TimerData *data = &SDL_timer_data;
SDL_TimerMap *prev, *entry; SDL_TimerMap *prev, *entry;
@@ -471,16 +468,94 @@ SDL_RemoveTimer(SDL_TimerID id)
return SDL_FALSE; return SDL_FALSE;
} }
#endif /* !defined(__EMSCRIPTEN__) || !SDL_THREADS_DISABLED */
static Uint64 tick_start;
static Uint64 tick_freq;
#if defined(SDL_TIMER_WINDOWS) && \
!defined(__WINRT__) && !defined(__XBOXONE__) && !defined(__XBOXSERIES__)
#include <timeapi.h>
#define HAVE_TIME_BEGIN_PERIOD
#endif #endif
/* This is a legacy support function; SDL_GetTicks() returns a Uint32, static void SDL_SetSystemTimerResolutionMS(int period)
which wraps back to zero every ~49 days. The newer SDL_GetTicks64()
doesn't have this problem, so we just wrap that function and clamp to
the low 32-bits for binary compatibility. */
Uint32
SDL_GetTicks(void)
{ {
return (Uint32)(SDL_GetTicks64() & 0xFFFFFFFF); #ifdef HAVE_TIME_BEGIN_PERIOD
static int timer_period = 0;
if (period != timer_period) {
if (timer_period) {
timeEndPeriod((UINT)timer_period);
}
timer_period = period;
if (timer_period) {
timeBeginPeriod((UINT)timer_period);
}
}
#endif /* HAVE_TIME_BEGIN_PERIOD */
}
static void SDLCALL SDL_TimerResolutionChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
{
int period;
/* Unless the hint says otherwise, let's have good sleep precision */
if (hint && *hint) {
period = SDL_atoi(hint);
} else {
period = 1;
}
if (period || oldValue != hint) {
SDL_SetSystemTimerResolutionMS(period);
}
}
void SDL_TicksInit(void)
{
if (tick_start) {
return;
}
/* If we didn't set a precision, set it high. This affects lots of things
on Windows besides the SDL timers, like audio callbacks, etc. */
SDL_AddHintCallback(SDL_HINT_TIMER_RESOLUTION,
SDL_TimerResolutionChanged, NULL);
tick_freq = SDL_GetPerformanceFrequency();
tick_start = SDL_GetPerformanceCounter();
}
void SDL_TicksQuit(void)
{
SDL_DelHintCallback(SDL_HINT_TIMER_RESOLUTION,
SDL_TimerResolutionChanged, NULL);
SDL_SetSystemTimerResolutionMS(0); /* always release our timer resolution request. */
tick_start = 0;
}
Uint64
SDL_GetTicksNS(void)
{
if (!tick_start) {
SDL_TicksInit();
}
return ((SDL_GetPerformanceCounter() - tick_start) * SDL_NS_PER_SECOND) / tick_freq;
}
Uint64 SDL_GetTicks(void)
{
return SDL_NS_TO_MS(SDL_GetTicksNS());
}
void SDL_Delay(Uint32 ms)
{
SDL_DelayNS(SDL_MS_TO_NS(ms));
} }
/* vi: set ts=4 sw=4 expandtab: */ /* vi: set ts=4 sw=4 expandtab: */

Some files were not shown because too many files have changed in this diff Show More