diff --git a/tests/testaudiomacros.pas b/tests/testaudiomacros.pas new file mode 100644 index 0000000..55aa55b --- /dev/null +++ b/tests/testaudiomacros.pas @@ -0,0 +1,31 @@ +{ + This file is part of: + + SDL3 for Pascal + (https://github.com/PascalGameDevelopment/SDL3-for-Pascal) + SPDX-License-Identifier: Zlib +} + +{ Test some macros from SDL_audio.inc } + +program testaudiomacros; + +uses + SDL3; + +begin + + SDL_Log('SDL_AUDIO_BITSIZE(SDL_AUDIO_S16) returns: %d (should be 16)',[SDL_AUDIO_BITSIZE(SDL_AUDIO_S16)]); + SDL_Log('SDL_AUDIO_BITSIZE(SDL_AUDIO_F32LE) returns: %d (should be 32)',[SDL_AUDIO_BITSIZE(SDL_AUDIO_F32LE)]); + SDL_Log('SDL_AUDIO_BYTESIZE(SDL_AUDIO_S16) returns: %d (should be 2)',[SDL_AUDIO_BYTESIZE(SDL_AUDIO_S16)]); + SDL_Log('SDL_AUDIO_ISFLOAT(SDL_AUDIO_S16) returns: %d (should be 0)',[SDL_AUDIO_ISFLOAT(SDL_AUDIO_S16)]); + SDL_Log('SDL_AUDIO_ISBIGENDIAN(SDL_AUDIO_S16LE) returns: %d (should be 0)',[SDL_AUDIO_ISBIGENDIAN(SDL_AUDIO_S16LE)]); + SDL_Log('SDL_AUDIO_ISBIGENDIAN(SDL_AUDIO_S16BE) returns: %d (should be )',[SDL_AUDIO_ISBIGENDIAN(SDL_AUDIO_S16BE)]); + SDL_Log('SDL_AUDIO_ISLITTLEENDIAN(SDL_AUDIO_S16BE) returns: %d (should be 0)',[SDL_AUDIO_ISLITTLEENDIAN(SDL_AUDIO_S16BE)]); + SDL_Log('SDL_AUDIO_ISLITTLEENDIAN(SDL_AUDIO_S16LE) returns: %d (should be )',[SDL_AUDIO_ISLITTLEENDIAN(SDL_AUDIO_S16LE)]); + SDL_Log('SDL_AUDIO_ISSIGNED(SDL_AUDIO_U8) returns: %d (should be 0)',[SDL_AUDIO_ISSIGNED(SDL_AUDIO_U8)]); + SDL_Log('SDL_AUDIO_ISINT(SDL_AUDIO_F32) returns: %d (should be 0)',[SDL_AUDIO_ISINT(SDL_AUDIO_F32)]); + SDL_Log('SDL_AUDIO_ISUNSIGNED(SDL_AUDIO_S16) returns: %d (should be 0)',[SDL_AUDIO_ISUNSIGNED(SDL_AUDIO_S16)]); + +end. + diff --git a/units/SDL3.pas b/units/SDL3.pas index 6f1435f..0098a6d 100644 --- a/units/SDL3.pas +++ b/units/SDL3.pas @@ -79,6 +79,7 @@ interface {$I SDL_log.inc} // 3.1.6-prev {$I SDL_version.inc} // 3.1.6-prev {$I SDL_revision.inc} // 3.1.6-prev +{$I SDL_guid.inc} // 3.1.6-prev {$I SDL_stdinc.inc} // 3.1.6-prev (unfinished) {$I SDL_rect.inc} // 3.1.6-prev {$I SDL_properties.inc} // 3.1.6-prev @@ -87,9 +88,21 @@ interface {$I SDL_iostream.inc} // 3.1.6-prev (unfinished) {$I SDL_surface.inc} // 3.1.6-prev {$I SDL_video.inc} // 3.1.6-prev -{$I SDL_render.inc} // 3.1.6-prev {$I SDL_timer.inc} // 3.1.6-prev {$I SDL_error.inc} // 3.1.6-prev +{$I SDL_power.inc} // 3.1.6-prev +{$I SDL_audio.inc} // 3.1.6-prev +{$I SDL_sensor.inc} // 3.1.6-prev +{$I SDL_scancode.inc} // 3.1.6-prev +{$I SDL_keycode.inc} // 3.1.6-prev +{$I SDL_mouse.inc} // 3.1.6-prev +{$I SDL_keyboard.inc} // 3.1.6-prev +{$I SDL_joystick.inc} // 3.1.6-prev +{$I SDL_pen.inc} // 3.1.6-prev +{$I SDL_touch.inc} // 3.1.6-prev +{$I SDL_camera.inc} // 3.1.6-prev +{$I SDL_events.inc} // 3.1.6-prev +{$I SDL_render.inc} // 3.1.6-prev implementation @@ -214,6 +227,64 @@ function SDL_NS_TO_US(NS: Integer): Integer; SDL_NS_TO_US:=NS div SDL_NS_PER_US; end; +{ Macros from SDL_audio.h } +function SDL_DEFINE_AUDIO_FORMAT(signed: cuint16; bigendian: cuint16; + float: cuint16; size: Integer): TSDL_AudioFormat; +begin + Result:=(signed shl 15) or (bigendian shl 12) or (float shl 8) or (size and SDL_AUDIO_MASK_BITSIZE); +end; + +function SDL_AUDIO_BITSIZE(x: TSDL_AudioFormat): Integer; +begin + Result:=x and SDL_AUDIO_MASK_BITSIZE; +end; + +function SDL_AUDIO_BYTESIZE(x: TSDL_AudioFormat): Integer; +begin + Result:=SDL_AUDIO_BITSIZE(x) div 8; +end; + +function SDL_AUDIO_ISFLOAT(x: TSDL_AudioFormat): Integer; +begin + Result:=x and SDL_AUDIO_MASK_FLOAT; +end; + +function SDL_AUDIO_ISBIGENDIAN(x: TSDL_AudioFormat): Integer; +begin + Result:=x and SDL_AUDIO_MASK_BIG_ENDIAN; +end; + +function SDL_AUDIO_ISLITTLEENDIAN(x: TSDL_AudioFormat): Integer; +begin + Result:=not(x) and SDL_AUDIO_MASK_BIG_ENDIAN; +end; + +function SDL_AUDIO_ISSIGNED(x: TSDL_AudioFormat): Integer; +begin + Result:=x and SDL_AUDIO_MASK_SIGNED; +end; + +function SDL_AUDIO_ISINT(x: TSDL_AudioFormat): Integer; +begin + Result:=not(x) and SDL_AUDIO_MASK_FLOAT; +end; + +function SDL_AUDIO_ISUNSIGNED(x: TSDL_AudioFormat): Integer; +begin + Result:=not(x) and SDL_AUDIO_MASK_SIGNED; +end; + +function SDL_AUDIO_FRAMESIZE(x: TSDL_AudioSpec): Integer; +begin + Result:=SDL_AUDIO_BYTESIZE(x.format * x.channels); +end; + +{ Macros from SDL_keycode.h } +function SDL_SCANCODE_TO_KEYCODE(X: TSDL_Scancode): TSDL_Keycode; +begin + Result:=X or SDLK_SCANCODE_MASK; +end; + { Macros from SDL_video.h } function SDL_WINDOWPOS_UNDEFINED_DISPLAY(X: Integer): Integer; begin diff --git a/units/SDL_audio.inc b/units/SDL_audio.inc new file mode 100644 index 0000000..c3585e4 --- /dev/null +++ b/units/SDL_audio.inc @@ -0,0 +1,2071 @@ +{ + This file is part of: + + SDL3 for Pascal + (https://github.com/PascalGameDevelopment/SDL3-for-Pascal) + SPDX-License-Identifier: Zlib +} + +{* + * # CategoryAudio + * + * Audio functionality for the SDL library. + * + * All audio in SDL3 revolves around SDL_AudioStream. Whether you want to play + * or record audio, convert it, stream it, buffer it, or mix it, you're going + * to be passing it through an audio stream. + * + * Audio streams are quite flexible; they can accept any amount of data at a + * time, in any supported format, and output it as needed in any other format, + * even if the data format changes on either side halfway through. + * + * An app opens an audio device and binds any number of audio streams to it, + * feeding more data to it as available. When the devices needs more data, it + * will pull it from all bound streams and mix them together for playback. + * + * Audio streams can also use an app-provided callback to supply data + * on-demand, which maps pretty closely to the SDL2 audio model. + * + * SDL also provides a simple .WAV loader in SDL_LoadWAV (and SDL_LoadWAV_IO + * if you aren't reading from a file) as a basic means to load sound data into + * your program. + * + * ## Logical audio devices + * + * In SDL3, opening a physical device (like a SoundBlaster 16 Pro) gives you a + * logical device ID that you can bind audio streams to. In almost all cases, + * logical devices can be used anywhere in the API that a physical device is + * normally used. However, since each device opening generates a new logical + * device, different parts of the program (say, a VoIP library, or + * text-to-speech framework, or maybe some other sort of mixer on top of SDL) + * can have their own device opens that do not interfere with each other; each + * logical device will mix its separate audio down to a single buffer, fed to + * the physical device, behind the scenes. As many logical devices as you like + * can come and go; SDL will only have to open the physical device at the OS + * level once, and will manage all the logical devices on top of it + * internally. + * + * One other benefit of logical devices: if you don't open a specific physical + * device, instead opting for the default, SDL can automatically migrate those + * logical devices to different hardware as circumstances change: a user + * plugged in headphones? The system default changed? SDL can transparently + * migrate the logical devices to the correct physical device seamlessly and + * keep playing; the app doesn't even have to know it happened if it doesn't + * want to. + * + * ## Channel layouts + * + * Audio data passing through SDL is uncompressed PCM data, interleaved. One + * can provide their own decompression through an MP3, etc, decoder, but SDL + * does not provide this directly. Each interleaved channel of data is meant + * to be in a specific order. + * + * Abbreviations: + * + * - FRONT = single mono speaker + * - FL = front left speaker + * - FR = front right speaker + * - FC = front center speaker + * - BL = back left speaker + * - BR = back right speaker + * - SR = surround right speaker + * - SL = surround left speaker + * - BC = back center speaker + * - LFE = low-frequency speaker + * + * These are listed in the order they are laid out in memory, so "FL, FR" + * means "the front left speaker is laid out in memory first, then the front + * right, then it repeats for the next audio frame". + * + * - 1 channel (mono) layout: FRONT + * - 2 channels (stereo) layout: FL, FR + * - 3 channels (2.1) layout: FL, FR, LFE + * - 4 channels (quad) layout: FL, FR, BL, BR + * - 5 channels (4.1) layout: FL, FR, LFE, BL, BR + * - 6 channels (5.1) layout: FL, FR, FC, LFE, BL, BR (last two can also be + * SL, SR) + * - 7 channels (6.1) layout: FL, FR, FC, LFE, BC, SL, SR + * - 8 channels (7.1) layout: FL, FR, FC, LFE, BL, BR, SL, SR + * + * This is the same order as DirectSound expects, but applied to all + * platforms; SDL will swizzle the channels as necessary if a platform expects + * something different. + * + * SDL_AudioStream can also be provided channel maps to change this ordering + * to whatever is necessary, in other audio processing scenarios. + } + +{ masks for different parts of SDL_AudioFormat. } +const + SDL_AUDIO_MASK_BITSIZE = $FF; + SDL_AUDIO_MASK_FLOAT = 1 shl 8; + SDL_AUDIO_MASK_BIG_ENDIAN = 1 shl 12; + SDL_AUDIO_MASK_SIGNED = 1 shl 15; + +{* + * Audio format. + * + * \since This enum is available since SDL 3.1.3. + * + * \sa SDL_AUDIO_BITSIZE + * \sa SDL_AUDIO_BYTESIZE + * \sa SDL_AUDIO_ISINT + * \sa SDL_AUDIO_ISFLOAT + * \sa SDL_AUDIO_ISBIGENDIAN + * \sa SDL_AUDIO_ISLITTLEENDIAN + * \sa SDL_AUDIO_ISSIGNED + * \sa SDL_AUDIO_ISUNSIGNED + } +type + PPSDL_AudioFormat = ^PSDL_AudioFormat; + PSDL_AudioFormat = ^TSDL_AudioFormat; + TSDL_AudioFormat = type Integer; +const + SDL_AUDIO_UNKNOWN = TSDL_AudioFormat($0000); {*< Unspecified audio format } + SDL_AUDIO_U8 = TSDL_AudioFormat($0008); {*< Unsigned 8-bit samples } + { SDL_DEFINE_AUDIO_FORMAT(0, 0, 0, 8), } + SDL_AUDIO_S8 = TSDL_AudioFormat($8008); {*< Signed 8-bit samples } + { SDL_DEFINE_AUDIO_FORMAT(1, 0, 0, 8), } + SDL_AUDIO_S16LE = TSDL_AudioFormat($8010); {*< Signed 16-bit samples } + { SDL_DEFINE_AUDIO_FORMAT(1, 0, 0, 16), } + SDL_AUDIO_S16BE = TSDL_AudioFormat($9010); {*< As above, but big-endian byte order } + { SDL_DEFINE_AUDIO_FORMAT(1, 1, 0, 16), } + SDL_AUDIO_S32LE = TSDL_AudioFormat($8020); {*< 32-bit integer samples } + { SDL_DEFINE_AUDIO_FORMAT(1, 0, 0, 32), } + SDL_AUDIO_S32BE = TSDL_AudioFormat($9020); {*< As above, but big-endian byte order } + { SDL_DEFINE_AUDIO_FORMAT(1, 1, 0, 32), } + SDL_AUDIO_F32LE = TSDL_AudioFormat($8120); {*< 32-bit floating point samples } + { SDL_DEFINE_AUDIO_FORMAT(1, 0, 1, 32), } + SDL_AUDIO_F32BE = TSDL_AudioFormat($9120); {*< As above, but big-endian byte order } + { SDL_DEFINE_AUDIO_FORMAT(1, 1, 1, 32), } + + { These represent the current system's byteorder. } + {$IFDEF ENDIAN_LITTLE} {SDL3-for-Pascal: ENDIAN_LITTLE is known by FPC and Delphi} + SDL_AUDIO_S16 = SDL_AUDIO_S16LE; + SDL_AUDIO_S32 = SDL_AUDIO_S32LE; + SDL_AUDIO_F32 = SDL_AUDIO_F32LE; + {$ELSE} + SDL_AUDIO_S16 = SDL_AUDIO_S16BE; + SDL_AUDIO_S32 = SDL_AUDIO_S32BE; + SDL_AUDIO_F32 = SDL_AUDIO_F32BE; + {$ENDIF} + +{ SDL3-for-Pascal: Moved SDL_DEFINE_AUDIO_FORMAT macro below TSDL_AudioFormat declaration to access it. } +function SDL_DEFINE_AUDIO_FORMAT(signed: cuint16; bigendian: cuint16; float: cuint16; size: Integer): TSDL_AudioFormat; + +{* + * Retrieve the size, in bits, from an SDL_AudioFormat. + * + * For example, `SDL_AUDIO_BITSIZE(SDL_AUDIO_S16)` returns 16. + * + * \param x an SDL_AudioFormat value. + * \returns data size in bits. + * + * \threadsafety It is safe to call this macro from any thread. + * + * \since This macro is available since SDL 3.1.3. + } +function SDL_AUDIO_BITSIZE(x: TSDL_AudioFormat): Integer; + +{* + * Retrieve the size, in bytes, from an SDL_AudioFormat. + * + * For example, `SDL_AUDIO_BYTESIZE(SDL_AUDIO_S16)` returns 2. + * + * \param x an SDL_AudioFormat value. + * \returns data size in bytes. + * + * \threadsafety It is safe to call this macro from any thread. + * + * \since This macro is available since SDL 3.1.3. + } +function SDL_AUDIO_BYTESIZE(x: TSDL_AudioFormat): Integer; + +{* + * Determine if an SDL_AudioFormat represents floating point data. + * + * For example, `SDL_AUDIO_ISFLOAT(SDL_AUDIO_S16)` returns 0. + * + * \param x an SDL_AudioFormat value. + * \returns non-zero if format is floating point, zero otherwise. + * + * \threadsafety It is safe to call this macro from any thread. + * + * \since This macro is available since SDL 3.1.3. + } +function SDL_AUDIO_ISFLOAT(x: TSDL_AudioFormat): Integer; + +{* + * Determine if an SDL_AudioFormat represents bigendian data. + * + * For example, `SDL_AUDIO_ISBIGENDIAN(SDL_AUDIO_S16LE)` returns 0. + * + * \param x an SDL_AudioFormat value. + * \returns non-zero if format is bigendian, zero otherwise. + * + * \threadsafety It is safe to call this macro from any thread. + * + * \since This macro is available since SDL 3.1.3. + } +function SDL_AUDIO_ISBIGENDIAN(x: TSDL_AudioFormat): Integer; + +{* + * Determine if an SDL_AudioFormat represents littleendian data. + * + * For example, `SDL_AUDIO_ISLITTLEENDIAN(SDL_AUDIO_S16BE)` returns 0. + * + * \param x an SDL_AudioFormat value. + * \returns non-zero if format is littleendian, zero otherwise. + * + * \threadsafety It is safe to call this macro from any thread. + * + * \since This macro is available since SDL 3.1.3. + } +function SDL_AUDIO_ISLITTLEENDIAN(x: TSDL_AudioFormat): Integer; + +{* + * Determine if an SDL_AudioFormat represents signed data. + * + * For example, `SDL_AUDIO_ISSIGNED(SDL_AUDIO_U8)` returns 0. + * + * \param x an SDL_AudioFormat value. + * \returns non-zero if format is signed, zero otherwise. + * + * \threadsafety It is safe to call this macro from any thread. + * + * \since This macro is available since SDL 3.1.3. + } +function SDL_AUDIO_ISSIGNED(x: TSDL_AudioFormat): Integer; + +{* + * Determine if an SDL_AudioFormat represents integer data. + * + * For example, `SDL_AUDIO_ISINT(SDL_AUDIO_F32)` returns 0. + * + * \param x an SDL_AudioFormat value. + * \returns non-zero if format is integer, zero otherwise. + * + * \threadsafety It is safe to call this macro from any thread. + * + * \since This macro is available since SDL 3.1.3. + } +function SDL_AUDIO_ISINT(x: TSDL_AudioFormat): Integer; + +{* + * Determine if an SDL_AudioFormat represents unsigned data. + * + * For example, `SDL_AUDIO_ISUNSIGNED(SDL_AUDIO_S16)` returns 0. + * + * \param x an SDL_AudioFormat value. + * \returns non-zero if format is unsigned, zero otherwise. + * + * \threadsafety It is safe to call this macro from any thread. + * + * \since This macro is available since SDL 3.1.3. + } +function SDL_AUDIO_ISUNSIGNED(x: TSDL_AudioFormat): Integer; + +{* + * SDL Audio Device instance IDs. + * + * Zero is used to signify an invalid/null device. + * + * \since This datatype is available since SDL 3.1.3. + } +type + PPSDL_AudioDeviceID = ^PSDL_AudioDeviceID; + PSDL_AudioDeviceID = ^TSDL_AudioDeviceID; + TSDL_AudioDeviceID = type cuint32; + +{* + * A value used to request a default playback audio device. + * + * Several functions that require an SDL_AudioDeviceID will accept this value + * to signify the app just wants the system to choose a default device instead + * of the app providing a specific one. + * + * \since This macro is available since SDL 3.1.3. + } +const + SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK = TSDL_AudioDeviceID($FFFFFFFF); + +{* + * A value used to request a default recording audio device. + * + * Several functions that require an SDL_AudioDeviceID will accept this value + * to signify the app just wants the system to choose a default device instead + * of the app providing a specific one. + * + * \since This macro is available since SDL 3.1.3. + } +const + SDL_AUDIO_DEVICE_DEFAULT_RECORDING = TSDL_AudioDeviceID($FFFFFFFE); + +{* + * Format specifier for audio data. + * + * \since This struct is available since SDL 3.1.3. + * + * \sa SDL_AudioFormat + } +type + PPSDL_AudioSpec = ^PSDL_AudioSpec; + PSDL_AudioSpec = ^TSDL_AudioSpec; + TSDL_AudioSpec = record + format: TSDL_AudioFormat; {*< Audio data format } + channels: cint; {*< Number of channels: 1 mono, 2 stereo, etc } + freq: cint; {*< sample rate: sample frames per second } + end; + +{* + * Calculate the size of each audio frame (in bytes) from an SDL_AudioSpec. + * + * This reports on the size of an audio sample frame: stereo Sint16 data (2 + * channels of 2 bytes each) would be 4 bytes per frame, for example. + * + * \param x an SDL_AudioSpec to query. + * \returns the number of bytes used per sample frame. + * + * \threadsafety It is safe to call this macro from any thread. + * + * \since This macro is available since SDL 3.1.3. + } +function SDL_AUDIO_FRAMESIZE(x: TSDL_AudioSpec): Integer; + +{* + * The opaque handle that represents an audio stream. + * + * SDL_AudioStream is an audio conversion interface. + * + * - It can handle resampling data in chunks without generating artifacts, + * when it doesn't have the complete buffer available. + * - It can handle incoming data in any variable size. + * - It can handle input/output format changes on the fly. + * - It can remap audio channels between inputs and outputs. + * - You push data as you have it, and pull it when you need it + * - It can also function as a basic audio data queue even if you just have + * sound that needs to pass from one place to another. + * - You can hook callbacks up to them when more data is added or requested, + * to manage data on-the-fly. + * + * Audio streams are the core of the SDL3 audio interface. You create one or + * more of them, bind them to an opened audio device, and feed data to them + * (or for recording, consume data from them). + * + * \since This struct is available since SDL 3.1.3. + * + * \sa SDL_CreateAudioStream + } +type + PPSDL_AudioStream = ^PSDL_AudioStream; + PSDL_AudioStream = type Pointer; + +{ Function prototypes } + +{* + * \name Driver discovery functions + * + * These functions return the list of built in audio drivers, in the + * order that they are normally initialized by default. + } +{ @ } +{* + * Use this function to get the number of built-in audio drivers. + * + * This function returns a hardcoded number. This never returns a negative + * value; if there are no drivers compiled into this build of SDL, this + * function returns zero. The presence of a driver in this list does not mean + * it will function, it just means SDL is capable of interacting with that + * interface. For example, a build of SDL might have esound support, but if + * there's no esound server available, SDL's esound driver would fail if used. + * + * By default, SDL tries all drivers, in its preferred order, until one is + * found to be usable. + * + * \returns the number of built-in audio drivers. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetAudioDriver + } +function SDL_GetNumAudioDrivers: cint; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetNumAudioDrivers' {$ENDIF} {$ENDIF}; + +{* + * Use this function to get the name of a built in audio driver. + * + * The list of audio drivers is given in the order that they are normally + * initialized by default; the drivers that seem more reasonable to choose + * first (as far as the SDL developers believe) are earlier in the list. + * + * The names of drivers are all simple, low-ASCII identifiers, like "alsa", + * "coreaudio" or "wasapi". These never have Unicode characters, and are not + * meant to be proper names. + * + * \param index the index of the audio driver; the value ranges from 0 to + * SDL_GetNumAudioDrivers() - 1. + * \returns the name of the audio driver at the requested index, or nil if an + * invalid index was specified. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetNumAudioDrivers + } +function SDL_GetAudioDriver(index: cint): PAnsiChar; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetAudioDriver' {$ENDIF} {$ENDIF}; + +{ @ } +{* + * Get the name of the current audio driver. + * + * The names of drivers are all simple, low-ASCII identifiers, like "alsa", + * "coreaudio" or "wasapi". These never have Unicode characters, and are not + * meant to be proper names. + * + * \returns the name of the current audio driver or nil if no driver has been + * initialized. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + } +function SDL_GetCurrentAudioDriver: PAnsiChar; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetCurrentAudioDriver' {$ENDIF} {$ENDIF}; + +{* + * Get a list of currently-connected audio playback devices. + * + * This returns of list of available devices that play sound, perhaps to + * speakers or headphones ("playback" devices). If you want devices that + * record audio, like a microphone ("recording" devices), use + * SDL_GetAudioRecordingDevices() instead. + * + * This only returns a list of physical devices; it will not have any device + * IDs returned by SDL_OpenAudioDevice(). + * + * If this function returns nil, to signify an error, `*count` will be set to + * zero. + * + * \param count a Pointer filled in with the number of devices returned, may + * be nil. + * \returns a 0 terminated array of device instance IDs or nil on error; call + * SDL_GetError() for more information. This should be freed with + * SDL_free() when it is no longer needed. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_OpenAudioDevice + * \sa SDL_GetAudioRecordingDevices + } +function SDL_GetAudioPlaybackDevices(count: pcint): PSDL_AudioDeviceID; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetAudioPlaybackDevices' {$ENDIF} {$ENDIF}; + +{* + * Get a list of currently-connected audio recording devices. + * + * This returns of list of available devices that record audio, like a + * microphone ("recording" devices). If you want devices that play sound, + * perhaps to speakers or headphones ("playback" devices), use + * SDL_GetAudioPlaybackDevices() instead. + * + * This only returns a list of physical devices; it will not have any device + * IDs returned by SDL_OpenAudioDevice(). + * + * If this function returns nil, to signify an error, `*count` will be set to + * zero. + * + * \param count a Pointer filled in with the number of devices returned, may + * be nil. + * \returns a 0 terminated array of device instance IDs, or nil on failure; + * call SDL_GetError() for more information. This should be freed + * with SDL_free() when it is no longer needed. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_OpenAudioDevice + * \sa SDL_GetAudioPlaybackDevices + } +function SDL_GetAudioRecordingDevices(count: pcint): PSDL_AudioDeviceID; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetAudioRecordingDevices' {$ENDIF} {$ENDIF}; + +{* + * Get the human-readable name of a specific audio device. + * + * \param devid the instance ID of the device to query. + * \returns the name of the audio device, or nil on failure; call + * SDL_GetError() for more information. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetAudioPlaybackDevices + * \sa SDL_GetAudioRecordingDevices + * \sa SDL_GetDefaultAudioInfo + } +function SDL_GetAudioDeviceName(devid: TSDL_AudioDeviceID): PAnsiChar; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetAudioDeviceName' {$ENDIF} {$ENDIF}; + +{* + * Get the current audio format of a specific audio device. + * + * For an opened device, this will report the format the device is currently + * using. If the device isn't yet opened, this will report the device's + * preferred format (or a reasonable default if this can't be determined). + * + * You may also specify SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK or + * SDL_AUDIO_DEVICE_DEFAULT_RECORDING here, which is useful for getting a + * reasonable recommendation before opening the system-recommended default + * device. + * + * You can also use this to request the current device buffer size. This is + * specified in sample frames and represents the amount of data SDL will feed + * to the physical hardware in each chunk. This can be converted to + * milliseconds of audio with the following equation: + * + * `ms = (int) ((((Sint64) frames) * 1000) / spec.freq);` + * + * Buffer size is only important if you need low-level control over the audio + * playback timing. Most apps do not need this. + * + * \param devid the instance ID of the device to query. + * \param spec on return, will be filled with device details. + * \param sample_frames Pointer to store device buffer size, in sample frames. + * Can be nil. + * \returns true on success or false on failure; call SDL_GetError() for more + * information. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + } +function SDL_GetAudioDeviceFormat(devid: TSDL_AudioDeviceID; spec: PSDL_AudioSpec; sample_frames: pcint): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetAudioDeviceFormat' {$ENDIF} {$ENDIF}; + +{* + * Get the current channel map of an audio device. + * + * Channel maps are optional; most things do not need them, instead passing + * data in the [order that SDL expects](CategoryAudio#channel-layouts). + * + * Audio devices usually have no remapping applied. This is represented by + * returning nil, and does not signify an error. + * + * \param devid the instance ID of the device to query. + * \param count On output, set to number of channels in the map. Can be nil. + * \returns an array of the current channel mapping, with as many elements as + * the current output spec's channels, or nil if default. This + * should be freed with SDL_free() when it is no longer needed. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_SetAudioStreamInputChannelMap + } +function SDL_GetAudioDeviceChannelMap(devid: TSDL_AudioDeviceID; count: pcint): pcint; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetAudioDeviceChannelMap' {$ENDIF} {$ENDIF}; + +{* + * Open a specific audio device. + * + * You can open both playback and recording devices through this function. + * Playback devices will take data from bound audio streams, mix it, and send + * it to the hardware. Recording devices will feed any bound audio streams + * with a copy of any incoming data. + * + * An opened audio device starts out with no audio streams bound. To start + * audio playing, bind a stream and supply audio data to it. Unlike SDL2, + * there is no audio callback; you only bind audio streams and make sure they + * have data flowing into them (however, you can simulate SDL2's semantics + * fairly closely by using SDL_OpenAudioDeviceStream instead of this + * function). + * + * If you don't care about opening a specific device, pass a `devid` of either + * `SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK` or + * `SDL_AUDIO_DEVICE_DEFAULT_RECORDING`. In this case, SDL will try to pick + * the most reasonable default, and may also switch between physical devices + * seamlessly later, if the most reasonable default changes during the + * lifetime of this opened device (user changed the default in the OS's system + * preferences, the default got unplugged so the system jumped to a new + * default, the user plugged in headphones on a mobile device, etc). Unless + * you have a good reason to choose a specific device, this is probably what + * you want. + * + * You may request a specific format for the audio device, but there is no + * promise the device will honor that request for several reasons. As such, + * it's only meant to be a hint as to what data your app will provide. Audio + * streams will accept data in whatever format you specify and manage + * conversion for you as appropriate. SDL_GetAudioDeviceFormat can tell you + * the preferred format for the device before opening and the actual format + * the device is using after opening. + * + * It's legal to open the same device ID more than once; each successful open + * will generate a new logical SDL_AudioDeviceID that is managed separately + * from others on the same physical device. This allows libraries to open a + * device separately from the main app and bind its own streams without + * conflicting. + * + * It is also legal to open a device ID returned by a previous call to this + * function; doing so just creates another logical device on the same physical + * device. This may be useful for making logical groupings of audio streams. + * + * This function returns the opened device ID on success. This is a new, + * unique SDL_AudioDeviceID that represents a logical device. + * + * Some backends might offer arbitrary devices (for example, a networked audio + * protocol that can connect to an arbitrary server). For these, as a change + * from SDL2, you should open a default device ID and use an SDL hint to + * specify the target if you care, or otherwise let the backend figure out a + * reasonable default. Most backends don't offer anything like this, and often + * this would be an end user setting an environment variable for their custom + * need, and not something an application should specifically manage. + * + * When done with an audio device, possibly at the end of the app's life, one + * should call SDL_CloseAudioDevice() on the returned device id. + * + * \param devid the device instance id to open, or + * SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK or + * SDL_AUDIO_DEVICE_DEFAULT_RECORDING for the most reasonable + * default device. + * \param spec the requested device configuration. Can be nil to use + * reasonable defaults. + * \returns the device ID on success or 0 on failure; call SDL_GetError() for + * more information. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_CloseAudioDevice + * \sa SDL_GetAudioDeviceFormat + } +function SDL_OpenAudioDevice(devid: TSDL_AudioDeviceID; spec: PSDL_AudioSpec): TSDL_AudioDeviceID; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_OpenAudioDevice' {$ENDIF} {$ENDIF}; + +{* + * Use this function to pause audio playback on a specified device. + * + * This function pauses audio processing for a given device. Any bound audio + * streams will not progress, and no audio will be generated. Pausing one + * device does not prevent other unpaused devices from running. + * + * Unlike in SDL2, audio devices start in an _unpaused_ state, since an app + * has to bind a stream before any audio will flow. Pausing a paused device is + * a legal no-op. + * + * Pausing a device can be useful to halt all audio without unbinding all the + * audio streams. This might be useful while a game is paused, or a level is + * loading, etc. + * + * Physical devices can not be paused or unpaused, only logical devices + * created through SDL_OpenAudioDevice() can be. + * + * \param dev a device opened by SDL_OpenAudioDevice(). + * \returns true on success or false on failure; call SDL_GetError() for more + * information. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_ResumeAudioDevice + * \sa SDL_AudioDevicePaused + } +function SDL_PauseAudioDevice(dev: TSDL_AudioDeviceID): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_PauseAudioDevice' {$ENDIF} {$ENDIF}; + +{* + * Use this function to unpause audio playback on a specified device. + * + * This function unpauses audio processing for a given device that has + * previously been paused with SDL_PauseAudioDevice(). Once unpaused, any + * bound audio streams will begin to progress again, and audio can be + * generated. + * + * Unlike in SDL2, audio devices start in an _unpaused_ state, since an app + * has to bind a stream before any audio will flow. Unpausing an unpaused + * device is a legal no-op. + * + * Physical devices can not be paused or unpaused, only logical devices + * created through SDL_OpenAudioDevice() can be. + * + * \param dev a device opened by SDL_OpenAudioDevice(). + * \returns true on success or false on failure; call SDL_GetError() for more + * information. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_AudioDevicePaused + * \sa SDL_PauseAudioDevice + } +function SDL_ResumeAudioDevice(dev: TSDL_AudioDeviceID): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_ResumeAudioDevice' {$ENDIF} {$ENDIF}; + +{* + * Use this function to query if an audio device is paused. + * + * Unlike in SDL2, audio devices start in an _unpaused_ state, since an app + * has to bind a stream before any audio will flow. + * + * Physical devices can not be paused or unpaused, only logical devices + * created through SDL_OpenAudioDevice() can be. Physical and invalid device + * IDs will report themselves as unpaused here. + * + * \param dev a device opened by SDL_OpenAudioDevice(). + * \returns true if device is valid and paused, false otherwise. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_PauseAudioDevice + * \sa SDL_ResumeAudioDevice + } +function SDL_AudioDevicePaused(dev: TSDL_AudioDeviceID): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_AudioDevicePaused' {$ENDIF} {$ENDIF}; + +{* + * Get the gain of an audio device. + * + * The gain of a device is its volume; a larger gain means a louder output, + * with a gain of zero being silence. + * + * Audio devices default to a gain of 1.0f (no change in output). + * + * Physical devices may not have their gain changed, only logical devices, and + * this function will always return -1.0f when used on physical devices. + * + * \param devid the audio device to query. + * \returns the gain of the device or -1.0f on failure; call SDL_GetError() + * for more information. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_SetAudioDeviceGain + } +function SDL_GetAudioDeviceGain(devid: TSDL_AudioDeviceID): cfloat; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetAudioDeviceGain' {$ENDIF} {$ENDIF}; + +{* + * Change the gain of an audio device. + * + * The gain of a device is its volume; a larger gain means a louder output, + * with a gain of zero being silence. + * + * Audio devices default to a gain of 1.0f (no change in output). + * + * Physical devices may not have their gain changed, only logical devices, and + * this function will always return false when used on physical devices. While + * it might seem attractive to adjust several logical devices at once in this + * way, it would allow an app or library to interfere with another portion of + * the program's otherwise-isolated devices. + * + * This is applied, along with any per-audiostream gain, during playback to + * the hardware, and can be continuously changed to create various effects. On + * recording devices, this will adjust the gain before passing the data into + * an audiostream; that recording audiostream can then adjust its gain further + * when outputting the data elsewhere, if it likes, but that second gain is + * not applied until the data leaves the audiostream again. + * + * \param devid the audio device on which to change gain. + * \param gain the gain. 1.0f is no change, 0.0f is silence. + * \returns true on success or false on failure; call SDL_GetError() for more + * information. + * + * \threadsafety It is safe to call this function from any thread, as it holds + * a stream-specific mutex while running. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetAudioDeviceGain + } +function SDL_SetAudioDeviceGain(devid: TSDL_AudioDeviceID; gain: cfloat): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetAudioDeviceGain' {$ENDIF} {$ENDIF}; + +{* + * Close a previously-opened audio device. + * + * The application should close open audio devices once they are no longer + * needed. + * + * This function may block briefly while pending audio data is played by the + * hardware, so that applications don't drop the last buffer of data they + * supplied if terminating immediately afterwards. + * + * \param devid an audio device id previously returned by + * SDL_OpenAudioDevice(). + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_OpenAudioDevice + } +procedure SDL_CloseAudioDevice(devid: TSDL_AudioDeviceID); cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_CloseAudioDevice' {$ENDIF} {$ENDIF}; + +{* + * Bind a list of audio streams to an audio device. + * + * Audio data will flow through any bound streams. For a playback device, data + * for all bound streams will be mixed together and fed to the device. For a + * recording device, a copy of recorded data will be provided to each bound + * stream. + * + * Audio streams can only be bound to an open device. This operation is + * atomic--all streams bound in the same call will start processing at the + * same time, so they can stay in sync. Also: either all streams will be bound + * or none of them will be. + * + * It is an error to bind an already-bound stream; it must be explicitly + * unbound first. + * + * Binding a stream to a device will set its output format for playback + * devices, and its input format for recording devices, so they match the + * device's settings. The caller is welcome to change the other end of the + * stream's format at any time. + * + * \param devid an audio device to bind a stream to. + * \param streams an array of audio streams to bind. + * \param num_streams number streams listed in the `streams` array. + * \returns true on success or false on failure; call SDL_GetError() for more + * information. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_BindAudioStreams + * \sa SDL_UnbindAudioStream + * \sa SDL_GetAudioStreamDevice + } +function SDL_BindAudioStreams(devid: TSDL_AudioDeviceID; streams: PPSDL_AudioStream; num_streams: cint): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_BindAudioStreams' {$ENDIF} {$ENDIF}; + +{* + * Bind a single audio stream to an audio device. + * + * This is a convenience function, equivalent to calling + * `SDL_BindAudioStreams(devid, &stream, 1)`. + * + * \param devid an audio device to bind a stream to. + * \param stream an audio stream to bind to a device. + * \returns true on success or false on failure; call SDL_GetError() for more + * information. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_BindAudioStreams + * \sa SDL_UnbindAudioStream + * \sa SDL_GetAudioStreamDevice + } +function SDL_BindAudioStream(devid: TSDL_AudioDeviceID; stream: PSDL_AudioStream): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_BindAudioStream' {$ENDIF} {$ENDIF}; + +{* + * Unbind a list of audio streams from their audio devices. + * + * The streams being unbound do not all have to be on the same device. All + * streams on the same device will be unbound atomically (data will stop + * flowing through all unbound streams on the same device at the same time). + * + * Unbinding a stream that isn't bound to a device is a legal no-op. + * + * \param streams an array of audio streams to unbind. + * \param num_streams number streams listed in the `streams` array. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_BindAudioStreams + } +procedure SDL_UnbindAudioStreams(streams: PPSDL_AudioStream; num_streams: cint); cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_UnbindAudioStreams' {$ENDIF} {$ENDIF}; + +{* + * Unbind a single audio stream from its audio device. + * + * This is a convenience function, equivalent to calling + * `SDL_UnbindAudioStreams(&stream, 1)`. + * + * \param stream an audio stream to unbind from a device. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_BindAudioStream + } +procedure SDL_UnbindAudioStream(stream: PSDL_AudioStream); cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_UnbindAudioStream' {$ENDIF} {$ENDIF}; + +{* + * Query an audio stream for its currently-bound device. + * + * This reports the audio device that an audio stream is currently bound to. + * + * If not bound, or invalid, this returns zero, which is not a valid device + * ID. + * + * \param stream the audio stream to query. + * \returns the bound audio device, or 0 if not bound or invalid. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_BindAudioStream + * \sa SDL_BindAudioStreams + } +function SDL_GetAudioStreamDevice(stream: PSDL_AudioStream): TSDL_AudioDeviceID; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetAudioStreamDevice' {$ENDIF} {$ENDIF}; + +{* + * Create a new audio stream. + * + * \param src_spec the format details of the input audio. + * \param dst_spec the format details of the output audio. + * \returns a new audio stream on success or nil on failure; call + * SDL_GetError() for more information. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_PutAudioStreamData + * \sa SDL_GetAudioStreamData + * \sa SDL_GetAudioStreamAvailable + * \sa SDL_FlushAudioStream + * \sa SDL_ClearAudioStream + * \sa SDL_SetAudioStreamFormat + * \sa SDL_DestroyAudioStream + } +function SDL_CreateAudioStream(src_spec: PSDL_AudioSpec; dst_spec: PSDL_AudioSpec): PSDL_AudioStream; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_CreateAudioStream' {$ENDIF} {$ENDIF}; + +{* + * Get the properties associated with an audio stream. + * + * \param stream the SDL_AudioStream to query. + * \returns a valid property ID on success or 0 on failure; call + * SDL_GetError() for more information. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + } +function SDL_GetAudioStreamProperties(stream: PSDL_AudioStream): TSDL_PropertiesID; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetAudioStreamProperties' {$ENDIF} {$ENDIF}; + +{* + * Query the current format of an audio stream. + * + * \param stream the SDL_AudioStream to query. + * \param src_spec where to store the input audio format; ignored if nil. + * \param dst_spec where to store the output audio format; ignored if nil. + * \returns true on success or false on failure; call SDL_GetError() for more + * information. + * + * \threadsafety It is safe to call this function from any thread, as it holds + * a stream-specific mutex while running. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_SetAudioStreamFormat + } +function SDL_GetAudioStreamFormat(stream: PSDL_AudioStream; src_spec: PSDL_AudioSpec; dst_spec: PSDL_AudioSpec): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetAudioStreamFormat' {$ENDIF} {$ENDIF}; + +{* + * Change the input and output formats of an audio stream. + * + * Future calls to and SDL_GetAudioStreamAvailable and SDL_GetAudioStreamData + * will reflect the new format, and future calls to SDL_PutAudioStreamData + * must provide data in the new input formats. + * + * Data that was previously queued in the stream will still be operated on in + * the format that was current when it was added, which is to say you can put + * the end of a sound file in one format to a stream, change formats for the + * next sound file, and start putting that new data while the previous sound + * file is still queued, and everything will still play back correctly. + * + * \param stream the stream the format is being changed. + * \param src_spec the new format of the audio input; if nil, it is not + * changed. + * \param dst_spec the new format of the audio output; if nil, it is not + * changed. + * \returns true on success or false on failure; call SDL_GetError() for more + * information. + * + * \threadsafety It is safe to call this function from any thread, as it holds + * a stream-specific mutex while running. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetAudioStreamFormat + * \sa SDL_SetAudioStreamFrequencyRatio + } +function SDL_SetAudioStreamFormat(stream: PSDL_AudioStream; src_spec: PSDL_AudioSpec; dst_spec: PSDL_AudioSpec): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetAudioStreamFormat' {$ENDIF} {$ENDIF}; + +{* + * Get the frequency ratio of an audio stream. + * + * \param stream the SDL_AudioStream to query. + * \returns the frequency ratio of the stream or 0.0 on failure; call + * SDL_GetError() for more information. + * + * \threadsafety It is safe to call this function from any thread, as it holds + * a stream-specific mutex while running. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_SetAudioStreamFrequencyRatio + } +function SDL_GetAudioStreamFrequencyRatio(stream: PSDL_AudioStream): cfloat; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetAudioStreamFrequencyRatio' {$ENDIF} {$ENDIF}; + +{* + * Change the frequency ratio of an audio stream. + * + * The frequency ratio is used to adjust the rate at which input data is + * consumed. Changing this effectively modifies the speed and pitch of the + * audio. A value greater than 1.0 will play the audio faster, and at a higher + * pitch. A value less than 1.0 will play the audio slower, and at a lower + * pitch. + * + * This is applied during SDL_GetAudioStreamData, and can be continuously + * changed to create various effects. + * + * \param stream the stream the frequency ratio is being changed. + * \param ratio the frequency ratio. 1.0 is normal speed. Must be between 0.01 + * and 100. + * \returns true on success or false on failure; call SDL_GetError() for more + * information. + * + * \threadsafety It is safe to call this function from any thread, as it holds + * a stream-specific mutex while running. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetAudioStreamFrequencyRatio + * \sa SDL_SetAudioStreamFormat + } +function SDL_SetAudioStreamFrequencyRatio(stream: PSDL_AudioStream; ratio: cfloat): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetAudioStreamFrequencyRatio' {$ENDIF} {$ENDIF}; + +{* + * Get the gain of an audio stream. + * + * The gain of a stream is its volume; a larger gain means a louder output, + * with a gain of zero being silence. + * + * Audio streams default to a gain of 1.0f (no change in output). + * + * \param stream the SDL_AudioStream to query. + * \returns the gain of the stream or -1.0f on failure; call SDL_GetError() + * for more information. + * + * \threadsafety It is safe to call this function from any thread, as it holds + * a stream-specific mutex while running. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_SetAudioStreamGain + } +function SDL_GetAudioStreamGain(stream: PSDL_AudioStream): cfloat; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetAudioStreamGain' {$ENDIF} {$ENDIF}; + +{* + * Change the gain of an audio stream. + * + * The gain of a stream is its volume; a larger gain means a louder output, + * with a gain of zero being silence. + * + * Audio streams default to a gain of 1.0f (no change in output). + * + * This is applied during SDL_GetAudioStreamData, and can be continuously + * changed to create various effects. + * + * \param stream the stream on which the gain is being changed. + * \param gain the gain. 1.0f is no change, 0.0f is silence. + * \returns true on success or false on failure; call SDL_GetError() for more + * information. + * + * \threadsafety It is safe to call this function from any thread, as it holds + * a stream-specific mutex while running. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetAudioStreamGain + } +function SDL_SetAudioStreamGain(stream: PSDL_AudioStream; gain: cfloat): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetAudioStreamGain' {$ENDIF} {$ENDIF}; + +{* + * Get the current input channel map of an audio stream. + * + * Channel maps are optional; most things do not need them, instead passing + * data in the [order that SDL expects](CategoryAudio#channel-layouts). + * + * Audio streams default to no remapping applied. This is represented by + * returning nil, and does not signify an error. + * + * \param stream the SDL_AudioStream to query. + * \param count On output, set to number of channels in the map. Can be nil. + * \returns an array of the current channel mapping, with as many elements as + * the current output spec's channels, or nil if default. This + * should be freed with SDL_free() when it is no longer needed. + * + * \threadsafety It is safe to call this function from any thread, as it holds + * a stream-specific mutex while running. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_SetAudioStreamInputChannelMap + } +function SDL_GetAudioStreamInputChannelMap(stream: PSDL_AudioStream; count: pcint): pcint; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetAudioStreamInputChannelMap' {$ENDIF} {$ENDIF}; + +{* + * Get the current output channel map of an audio stream. + * + * Channel maps are optional; most things do not need them, instead passing + * data in the [order that SDL expects](CategoryAudio#channel-layouts). + * + * Audio streams default to no remapping applied. This is represented by + * returning nil, and does not signify an error. + * + * \param stream the SDL_AudioStream to query. + * \param count On output, set to number of channels in the map. Can be nil. + * \returns an array of the current channel mapping, with as many elements as + * the current output spec's channels, or nil if default. This + * should be freed with SDL_free() when it is no longer needed. + * + * \threadsafety It is safe to call this function from any thread, as it holds + * a stream-specific mutex while running. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_SetAudioStreamInputChannelMap + } +function SDL_GetAudioStreamOutputChannelMap(stream: PSDL_AudioStream; count: pcint): pcint; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetAudioStreamOutputChannelMap' {$ENDIF} {$ENDIF}; + +{* + * Set the current input channel map of an audio stream. + * + * Channel maps are optional; most things do not need them, instead passing + * data in the [order that SDL expects](CategoryAudio#channel-layouts). + * + * The input channel map reorders data that is added to a stream via + * SDL_PutAudioStreamData. Future calls to SDL_PutAudioStreamData must provide + * data in the new channel order. + * + * Each item in the array represents an input channel, and its value is the + * channel that it should be remapped to. To reverse a stereo signal's left + * and right values, you'd have an array of ` 1, 0 `. It is legal to remap + * multiple channels to the same thing, so ` 1, 1 ` would duplicate the + * right channel to both channels of a stereo signal. You cannot change the + * number of channels through a channel map, just reorder them. + * + * Data that was previously queued in the stream will still be operated on in + * the order that was current when it was added, which is to say you can put + * the end of a sound file in one order to a stream, change orders for the + * next sound file, and start putting that new data while the previous sound + * file is still queued, and everything will still play back correctly. + * + * Audio streams default to no remapping applied. Passing a nil channel map + * is legal, and turns off remapping. + * + * SDL will copy the channel map; the caller does not have to save this array + * after this call. + * + * If `count` is not equal to the current number of channels in the audio + * stream's format, this will fail. This is a safety measure to make sure a a + * race condition hasn't changed the format while you this call is setting the + * channel map. + * + * \param stream the SDL_AudioStream to change. + * \param chmap the new channel map, nil to reset to default. + * \param count The number of channels in the map. + * \returns true on success or false on failure; call SDL_GetError() for more + * information. + * + * \threadsafety It is safe to call this function from any thread, as it holds + * a stream-specific mutex while running. Don't change the + * stream's format to have a different number of channels from a + * a different thread at the same time, though! + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_SetAudioStreamInputChannelMap + } +function SDL_SetAudioStreamInputChannelMap(stream: PSDL_AudioStream; chmap: pcint; count: cint): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetAudioStreamInputChannelMap' {$ENDIF} {$ENDIF}; + +{* + * Set the current output channel map of an audio stream. + * + * Channel maps are optional; most things do not need them, instead passing + * data in the [order that SDL expects](CategoryAudio#channel-layouts). + * + * The output channel map reorders data that leaving a stream via + * SDL_GetAudioStreamData. + * + * Each item in the array represents an output channel, and its value is the + * channel that it should be remapped to. To reverse a stereo signal's left + * and right values, you'd have an array of ` 1, 0 `. It is legal to remap + * multiple channels to the same thing, so ` 1, 1 ` would duplicate the + * right channel to both channels of a stereo signal. You cannot change the + * number of channels through a channel map, just reorder them. + * + * The output channel map can be changed at any time, as output remapping is + * applied during SDL_GetAudioStreamData. + * + * Audio streams default to no remapping applied. Passing a nil channel map + * is legal, and turns off remapping. + * + * SDL will copy the channel map; the caller does not have to save this array + * after this call. + * + * If `count` is not equal to the current number of channels in the audio + * stream's format, this will fail. This is a safety measure to make sure a a + * race condition hasn't changed the format while you this call is setting the + * channel map. + * + * \param stream the SDL_AudioStream to change. + * \param chmap the new channel map, nil to reset to default. + * \param count The number of channels in the map. + * \returns true on success or false on failure; call SDL_GetError() for more + * information. + * + * \threadsafety It is safe to call this function from any thread, as it holds + * a stream-specific mutex while running. Don't change the + * stream's format to have a different number of channels from a + * a different thread at the same time, though! + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_SetAudioStreamInputChannelMap + } + +function SDL_SetAudioStreamOutputChannelMap(stream: PSDL_AudioStream; chmap: pcint; count: cint): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetAudioStreamOutputChannelMap' {$ENDIF} {$ENDIF}; + +{* + * Add data to the stream. + * + * This data must match the format/channels/samplerate specified in the latest + * call to SDL_SetAudioStreamFormat, or the format specified when creating the + * stream if it hasn't been changed. + * + * Note that this call simply copies the unconverted data for later. This is + * different than SDL2, where data was converted during the Put call and the + * Get call would just dequeue the previously-converted data. + * + * \param stream the stream the audio data is being added to. + * \param buf a Pointer to the audio data to add. + * \param len the number of bytes to write to the stream. + * \returns true on success or false on failure; call SDL_GetError() for more + * information. + * + * \threadsafety It is safe to call this function from any thread, but if the + * stream has a callback set, the caller might need to manage + * extra locking. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_ClearAudioStream + * \sa SDL_FlushAudioStream + * \sa SDL_GetAudioStreamData + * \sa SDL_GetAudioStreamQueued + } +function SDL_PutAudioStreamData(stream: PSDL_AudioStream; buf: Pointer; len: cint): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_PutAudioStreamData' {$ENDIF} {$ENDIF}; + +{* + * Get converted/resampled data from the stream. + * + * The input/output data format/channels/samplerate is specified when creating + * the stream, and can be changed after creation by calling + * SDL_SetAudioStreamFormat. + * + * Note that any conversion and resampling necessary is done during this call, + * and SDL_PutAudioStreamData simply queues unconverted data for later. This + * is different than SDL2, where that work was done while inputting new data + * to the stream and requesting the output just copied the converted data. + * + * \param stream the stream the audio is being requested from. + * \param buf a buffer to fill with audio data. + * \param len the maximum number of bytes to fill. + * \returns the number of bytes read from the stream or -1 on failure; call + * SDL_GetError() for more information. + * + * \threadsafety It is safe to call this function from any thread, but if the + * stream has a callback set, the caller might need to manage + * extra locking. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_ClearAudioStream + * \sa SDL_GetAudioStreamAvailable + * \sa SDL_PutAudioStreamData + } +function SDL_GetAudioStreamData(stream: PSDL_AudioStream; buf: Pointer; len: cint): cint; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetAudioStreamData' {$ENDIF} {$ENDIF}; + +{* + * Get the number of converted/resampled bytes available. + * + * The stream may be buffering data behind the scenes until it has enough to + * resample correctly, so this number might be lower than what you expect, or + * even be zero. Add more data or flush the stream if you need the data now. + * + * If the stream has so much data that it would overflow an int, the return + * value is clamped to a maximum value, but no queued data is lost; if there + * are gigabytes of data queued, the app might need to read some of it with + * SDL_GetAudioStreamData before this function's return value is no longer + * clamped. + * + * \param stream the audio stream to query. + * \returns the number of converted/resampled bytes available or -1 on + * failure; call SDL_GetError() for more information. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetAudioStreamData + * \sa SDL_PutAudioStreamData + } +function SDL_GetAudioStreamAvailable(stream: PSDL_AudioStream): cint; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetAudioStreamAvailable' {$ENDIF} {$ENDIF}; + +{* + * Get the number of bytes currently queued. + * + * This is the number of bytes put into a stream as input, not the number that + * can be retrieved as output. Because of several details, it's not possible + * to calculate one number directly from the other. If you need to know how + * much usable data can be retrieved right now, you should use + * SDL_GetAudioStreamAvailable() and not this function. + * + * Note that audio streams can change their input format at any time, even if + * there is still data queued in a different format, so the returned byte + * count will not necessarily match the number of _sample frames_ available. + * Users of this API should be aware of format changes they make when feeding + * a stream and plan accordingly. + * + * Queued data is not converted until it is consumed by + * SDL_GetAudioStreamData, so this value should be representative of the exact + * data that was put into the stream. + * + * If the stream has so much data that it would overflow an int, the return + * value is clamped to a maximum value, but no queued data is lost; if there + * are gigabytes of data queued, the app might need to read some of it with + * SDL_GetAudioStreamData before this function's return value is no longer + * clamped. + * + * \param stream the audio stream to query. + * \returns the number of bytes queued or -1 on failure; call SDL_GetError() + * for more information. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_PutAudioStreamData + * \sa SDL_ClearAudioStream + } +function SDL_GetAudioStreamQueued(stream: PSDL_AudioStream): cint; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetAudioStreamQueued' {$ENDIF} {$ENDIF}; + +{* + * Tell the stream that you're done sending data, and anything being buffered + * should be converted/resampled and made available immediately. + * + * It is legal to add more data to a stream after flushing, but there may be + * audio gaps in the output. Generally this is intended to signal the end of + * input, so the complete output becomes available. + * + * \param stream the audio stream to flush. + * \returns true on success or false on failure; call SDL_GetError() for more + * information. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_PutAudioStreamData + } +function SDL_FlushAudioStream(stream: PSDL_AudioStream): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_FlushAudioStream' {$ENDIF} {$ENDIF}; + +{* + * Clear any pending data in the stream. + * + * This drops any queued data, so there will be nothing to read from the + * stream until more is added. + * + * \param stream the audio stream to clear. + * \returns true on success or false on failure; call SDL_GetError() for more + * information. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetAudioStreamAvailable + * \sa SDL_GetAudioStreamData + * \sa SDL_GetAudioStreamQueued + * \sa SDL_PutAudioStreamData + } +function SDL_ClearAudioStream(stream: PSDL_AudioStream): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_ClearAudioStream' {$ENDIF} {$ENDIF}; + +{* + * Use this function to pause audio playback on the audio device associated + * with an audio stream. + * + * This function pauses audio processing for a given device. Any bound audio + * streams will not progress, and no audio will be generated. Pausing one + * device does not prevent other unpaused devices from running. + * + * Pausing a device can be useful to halt all audio without unbinding all the + * audio streams. This might be useful while a game is paused, or a level is + * loading, etc. + * + * \param stream the audio stream associated with the audio device to pause. + * \returns true on success or false on failure; call SDL_GetError() for more + * information. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_ResumeAudioStreamDevice + } +function SDL_PauseAudioStreamDevice(stream: PSDL_AudioStream): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_PauseAudioStreamDevice' {$ENDIF} {$ENDIF}; + +{* + * Use this function to unpause audio playback on the audio device associated + * with an audio stream. + * + * This function unpauses audio processing for a given device that has + * previously been paused. Once unpaused, any bound audio streams will begin + * to progress again, and audio can be generated. + * + * \param stream the audio stream associated with the audio device to resume. + * \returns true on success or false on failure; call SDL_GetError() for more + * information. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_PauseAudioStreamDevice + } +function SDL_ResumeAudioStreamDevice(stream: PSDL_AudioStream): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_ResumeAudioStreamDevice' {$ENDIF} {$ENDIF}; + +{* + * Lock an audio stream for serialized access. + * + * Each SDL_AudioStream has an internal mutex it uses to protect its data + * structures from threading conflicts. This function allows an app to lock + * that mutex, which could be useful if registering callbacks on this stream. + * + * One does not need to lock a stream to use in it most cases, as the stream + * manages this lock internally. However, this lock is held during callbacks, + * which may run from arbitrary threads at any time, so if an app needs to + * protect shared data during those callbacks, locking the stream guarantees + * that the callback is not running while the lock is held. + * + * As this is just a wrapper over SDL_LockMutex for an internal lock; it has + * all the same attributes (recursive locks are allowed, etc). + * + * \param stream the audio stream to lock. + * \returns true on success or false on failure; call SDL_GetError() for more + * information. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_UnlockAudioStream + } +function SDL_LockAudioStream(stream: PSDL_AudioStream): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_LockAudioStream' {$ENDIF} {$ENDIF}; + +{* + * Unlock an audio stream for serialized access. + * + * This unlocks an audio stream after a call to SDL_LockAudioStream. + * + * \param stream the audio stream to unlock. + * \returns true on success or false on failure; call SDL_GetError() for more + * information. + * + * \threadsafety You should only call this from the same thread that + * previously called SDL_LockAudioStream. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_LockAudioStream + } +function SDL_UnlockAudioStream(stream: PSDL_AudioStream): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_UnlockAudioStream' {$ENDIF} {$ENDIF}; + +{* + * A callback that fires when data passes through an SDL_AudioStream. + * + * Apps can (optionally) register a callback with an audio stream that is + * called when data is added with SDL_PutAudioStreamData, or requested with + * SDL_GetAudioStreamData. + * + * Two values are offered here: one is the amount of additional data needed to + * satisfy the immediate request (which might be zero if the stream already + * has enough data queued) and the other is the total amount being requested. + * In a Get call triggering a Put callback, these values can be different. In + * a Put call triggering a Get callback, these values are always the same. + * + * Byte counts might be slightly overestimated due to buffering or resampling, + * and may change from call to call. + * + * This callback is not required to do anything. Generally this is useful for + * adding/reading data on demand, and the app will often put/get data as + * appropriate, but the system goes on with the data currently available to it + * if this callback does nothing. + * + * \param stream the SDL audio stream associated with this callback. + * \param additional_amount the amount of data, in bytes, that is needed right + * now. + * \param total_amount the total amount of data requested, in bytes, that is + * requested or available. + * \param userdata an opaque Pointer provided by the app for their personal + * use. + * + * \threadsafety This callbacks may run from any thread, so if you need to + * protect shared data, you should use SDL_LockAudioStream to + * serialize access; this lock will be held before your callback + * is called, so your callback does not need to manage the lock + * explicitly. + * + * \since This datatype is available since SDL 3.1.3. + * + * \sa SDL_SetAudioStreamGetCallback + * \sa SDL_SetAudioStreamPutCallback + } +type + TSDL_AudioStreamCallback = procedure(userdata: Pointer; stream: PSDL_AudioStream; additional_amount: cint; total_amount: cint); cdecl; + +{* + * Set a callback that runs when data is requested from an audio stream. + * + * This callback is called _before_ data is obtained from the stream, giving + * the callback the chance to add more on-demand. + * + * The callback can (optionally) call SDL_PutAudioStreamData() to add more + * audio to the stream during this call; if needed, the request that triggered + * this callback will obtain the new data immediately. + * + * The callback's `approx_request` argument is roughly how many bytes of + * _unconverted_ data (in the stream's input format) is needed by the caller, + * although this may overestimate a little for safety. This takes into account + * how much is already in the stream and only asks for any extra necessary to + * resolve the request, which means the callback may be asked for zero bytes, + * and a different amount on each call. + * + * The callback is not required to supply exact amounts; it is allowed to + * supply too much or too little or none at all. The caller will get what's + * available, up to the amount they requested, regardless of this callback's + * outcome. + * + * Clearing or flushing an audio stream does not call this callback. + * + * This function obtains the stream's lock, which means any existing callback + * (get or put) in progress will finish running before setting the new + * callback. + * + * Setting a nil function turns off the callback. + * + * \param stream the audio stream to set the new callback on. + * \param callback the new callback function to call when data is requested + * from the stream. + * \param userdata an opaque Pointer provided to the callback for its own + * personal use. + * \returns true on success or false on failure; call SDL_GetError() for more + * information. This only fails if `stream` is nil. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_SetAudioStreamPutCallback + } +function SDL_SetAudioStreamGetCallback(stream: PSDL_AudioStream; callback: TSDL_AudioStreamCallback; userdata: Pointer): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetAudioStreamGetCallback' {$ENDIF} {$ENDIF}; + +{* + * Set a callback that runs when data is added to an audio stream. + * + * This callback is called _after_ the data is added to the stream, giving the + * callback the chance to obtain it immediately. + * + * The callback can (optionally) call SDL_GetAudioStreamData() to obtain audio + * from the stream during this call. + * + * The callback's `approx_request` argument is how many bytes of _converted_ + * data (in the stream's output format) was provided by the caller, although + * this may underestimate a little for safety. This value might be less than + * what is currently available in the stream, if data was already there, and + * might be less than the caller provided if the stream needs to keep a buffer + * to aid in resampling. Which means the callback may be provided with zero + * bytes, and a different amount on each call. + * + * The callback may call SDL_GetAudioStreamAvailable to see the total amount + * currently available to read from the stream, instead of the total provided + * by the current call. + * + * The callback is not required to obtain all data. It is allowed to read less + * or none at all. Anything not read now simply remains in the stream for + * later access. + * + * Clearing or flushing an audio stream does not call this callback. + * + * This function obtains the stream's lock, which means any existing callback + * (get or put) in progress will finish running before setting the new + * callback. + * + * Setting a nil function turns off the callback. + * + * \param stream the audio stream to set the new callback on. + * \param callback the new callback function to call when data is added to the + * stream. + * \param userdata an opaque Pointer provided to the callback for its own + * personal use. + * \returns true on success or false on failure; call SDL_GetError() for more + * information. This only fails if `stream` is nil. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_SetAudioStreamGetCallback + } +function SDL_SetAudioStreamPutCallback(stream: PSDL_AudioStream; callback: TSDL_AudioStreamCallback; userdata: Pointer): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetAudioStreamPutCallback' {$ENDIF} {$ENDIF}; + +{* + * Free an audio stream. + * + * This will release all allocated data, including any audio that is still + * queued. You do not need to manually clear the stream first. + * + * If this stream was bound to an audio device, it is unbound during this + * call. If this stream was created with SDL_OpenAudioDeviceStream, the audio + * device that was opened alongside this stream's creation will be closed, + * too. + * + * \param stream the audio stream to destroy. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_CreateAudioStream + } +procedure SDL_DestroyAudioStream(stream: PSDL_AudioStream); cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_DestroyAudioStream' {$ENDIF} {$ENDIF}; + +{* + * Convenience function for straightforward audio init for the common case. + * + * If all your app intends to do is provide a single source of PCM audio, this + * function allows you to do all your audio setup in a single call. + * + * This is also intended to be a clean means to migrate apps from SDL2. + * + * This function will open an audio device, create a stream and bind it. + * Unlike other methods of setup, the audio device will be closed when this + * stream is destroyed, so the app can treat the returned SDL_AudioStream as + * the only object needed to manage audio playback. + * + * Also unlike other functions, the audio device begins paused. This is to map + * more closely to SDL2-style behavior, since there is no extra step here to + * bind a stream to begin audio flowing. The audio device should be resumed + * with `SDL_ResumeAudioStreamDevice(stream);` + * + * This function works with both playback and recording devices. + * + * The `spec` parameter represents the app's side of the audio stream. That + * is, for recording audio, this will be the output format, and for playing + * audio, this will be the input format. If spec is nil, the system will + * choose the format, and the app can use SDL_GetAudioStreamFormat() to obtain + * this information later. + * + * If you don't care about opening a specific audio device, you can (and + * probably _should_), use SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK for playback and + * SDL_AUDIO_DEVICE_DEFAULT_RECORDING for recording. + * + * One can optionally provide a callback function; if nil, the app is + * expected to queue audio data for playback (or unqueue audio data if + * capturing). Otherwise, the callback will begin to fire once the device is + * unpaused. + * + * Destroying the returned stream with SDL_DestroyAudioStream will also close + * the audio device associated with this stream. + * + * \param devid an audio device to open, or SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK + * or SDL_AUDIO_DEVICE_DEFAULT_RECORDING. + * \param spec the audio stream's data format. Can be nil. + * \param callback a callback where the app will provide new data for + * playback, or receive new data for recording. Can be nil, + * in which case the app will need to call + * SDL_PutAudioStreamData or SDL_GetAudioStreamData as + * necessary. + * \param userdata app-controlled Pointer passed to callback. Can be nil. + * Ignored if callback is nil. + * \returns an audio stream on success, ready to use, or nil on failure; call + * SDL_GetError() for more information. When done with this stream, + * call SDL_DestroyAudioStream to free resources and close the + * device. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetAudioStreamDevice + * \sa SDL_ResumeAudioStreamDevice + } +function SDL_OpenAudioDeviceStream(devid: TSDL_AudioDeviceID; spec: PSDL_AudioSpec; callback: TSDL_AudioStreamCallback; userdata: Pointer): PSDL_AudioStream; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_OpenAudioDeviceStream' {$ENDIF} {$ENDIF}; + +{* + * A callback that fires when data is about to be fed to an audio device. + * + * This is useful for accessing the final mix, perhaps for writing a + * visualizer or applying a final effect to the audio data before playback. + * + * This callback should run as quickly as possible and not block for any + * significant time, as this callback delays submission of data to the audio + * device, which can cause audio playback problems. + * + * The postmix callback _must_ be able to handle any audio data format + * specified in `spec`, which can change between callbacks if the audio device + * changed. However, this only covers frequency and channel count; data is + * always provided here in SDL_AUDIO_F32 format. + * + * The postmix callback runs _after_ logical device gain and audiostream gain + * have been applied, which is to say you can make the output data louder at + * this point than the gain settings would suggest. + * + * \param userdata a Pointer provided by the app through + * SDL_SetAudioPostmixCallback, for its own use. + * \param spec the current format of audio that is to be submitted to the + * audio device. + * \param buffer the buffer of audio samples to be submitted. The callback can + * inspect and/or modify this data. + * \param buflen the size of `buffer` in bytes. + * + * \threadsafety This will run from a background thread owned by SDL. The + * application is responsible for locking resources the callback + * touches that need to be protected. + * + * \since This datatype is available since SDL 3.1.3. + * + * \sa SDL_SetAudioPostmixCallback + } +type + TSDL_AudioPostmixCallback = procedure(userdata: Pointer; spec: PSDL_AudioSpec; buffer: pcfloat; buflen: cint); cdecl; + +{* + * Set a callback that fires when data is about to be fed to an audio device. + * + * This is useful for accessing the final mix, perhaps for writing a + * visualizer or applying a final effect to the audio data before playback. + * + * The buffer is the final mix of all bound audio streams on an opened device; + * this callback will fire regularly for any device that is both opened and + * unpaused. If there is no new data to mix, either because no streams are + * bound to the device or all the streams are empty, this callback will still + * fire with the entire buffer set to silence. + * + * This callback is allowed to make changes to the data; the contents of the + * buffer after this call is what is ultimately passed along to the hardware. + * + * The callback is always provided the data in float format (values from -1.0f + * to 1.0f), but the number of channels or sample rate may be different than + * the format the app requested when opening the device; SDL might have had to + * manage a conversion behind the scenes, or the playback might have jumped to + * new physical hardware when a system default changed, etc. These details may + * change between calls. Accordingly, the size of the buffer might change + * between calls as well. + * + * This callback can run at any time, and from any thread; if you need to + * serialize access to your app's data, you should provide and use a mutex or + * other synchronization device. + * + * All of this to say: there are specific needs this callback can fulfill, but + * it is not the simplest interface. Apps should generally provide audio in + * their preferred format through an SDL_AudioStream and let SDL handle the + * difference. + * + * This function is extremely time-sensitive; the callback should do the least + * amount of work possible and return as quickly as it can. The longer the + * callback runs, the higher the risk of audio dropouts or other problems. + * + * This function will block until the audio device is in between iterations, + * so any existing callback that might be running will finish before this + * function sets the new callback and returns. + * + * Setting a nil callback function disables any previously-set callback. + * + * \param devid the ID of an opened audio device. + * \param callback a callback function to be called. Can be nil. + * \param userdata app-controlled Pointer passed to callback. Can be nil. + * \returns true on success or false on failure; call SDL_GetError() for more + * information. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + } +function SDL_SetAudioPostmixCallback(devid: TSDL_AudioDeviceID; callback: TSDL_AudioPostmixCallback; userdata: Pointer): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetAudioPostmixCallback' {$ENDIF} {$ENDIF}; + +{* + * Load the audio data of a WAVE file into memory. + * + * Loading a WAVE file requires `src`, `spec`, `audio_buf` and `audio_len` to + * be valid pointers. The entire data portion of the file is then loaded into + * memory and decoded if necessary. + * + * Supported formats are RIFF WAVE files with the formats PCM (8, 16, 24, and + * 32 bits), IEEE Float (32 bits), Microsoft ADPCM and IMA ADPCM (4 bits), and + * A-law and mu-law (8 bits). Other formats are currently unsupported and + * cause an error. + * + * If this function succeeds, the return value is zero and the Pointer to the + * audio data allocated by the function is written to `audio_buf` and its + * length in bytes to `audio_len`. The SDL_AudioSpec members `freq`, + * `channels`, and `format` are set to the values of the audio data in the + * buffer. + * + * It's necessary to use SDL_free() to free the audio data returned in + * `audio_buf` when it is no longer used. + * + * Because of the underspecification of the .WAV format, there are many + * problematic files in the wild that cause issues with strict decoders. To + * provide compatibility with these files, this decoder is lenient in regards + * to the truncation of the file, the fact chunk, and the size of the RIFF + * chunk. The hints `SDL_HINT_WAVE_RIFF_CHUNK_SIZE`, + * `SDL_HINT_WAVE_TRUNCATION`, and `SDL_HINT_WAVE_FACT_CHUNK` can be used to + * tune the behavior of the loading process. + * + * Any file that is invalid (due to truncation, corruption, or wrong values in + * the headers), too big, or unsupported causes an error. Additionally, any + * critical I/O error from the data source will terminate the loading process + * with an error. The function returns nil on error and in all cases (with + * the exception of `src` being nil), an appropriate error message will be + * set. + * + * It is required that the data source supports seeking. + * + * Example: + * + * ```c + * SDL_LoadWAV_IO(SDL_IOFromFile("sample.wav", "rb"), true, &spec, &buf, &len); + * ``` + * + * Note that the SDL_LoadWAV function does this same thing for you, but in a + * less messy way: + * + * ```c + * SDL_LoadWAV("sample.wav", &spec, &buf, &len); + * ``` + * + * \param src the data source for the WAVE data. + * \param closeio if true, calls SDL_CloseIO() on `src` before returning, even + * in the case of an error. + * \param spec a Pointer to an SDL_AudioSpec that will be set to the WAVE + * data's format details on successful return. + * \param audio_buf a Pointer filled with the audio data, allocated by the + * function. + * \param audio_len a Pointer filled with the length of the audio data buffer + * in bytes. + * \returns true on success. `audio_buf` will be filled with a Pointer to an + * allocated buffer containing the audio data, and `audio_len` is + * filled with the length of that audio buffer in bytes. + * + * This function returns false if the .WAV file cannot be opened, + * uses an unknown data format, or is corrupt; call SDL_GetError() + * for more information. + * + * When the application is done with the data returned in + * `audio_buf`, it should call SDL_free() to dispose of it. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_free + * \sa SDL_LoadWAV + } +function SDL_LoadWAV_IO(src: PSDL_IOStream; closeio: cbool; spec: PSDL_AudioSpec; audio_buf: ppcuint8; audio_len: pcuint32): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_LoadWAV_IO' {$ENDIF} {$ENDIF}; + +{* + * Loads a WAV from a file path. + * + * This is a convenience function that is effectively the same as: + * + * ```c + * SDL_LoadWAV_IO(SDL_IOFromFile(path, "rb"), true, spec, audio_buf, audio_len); + * ``` + * + * \param path the file path of the WAV file to open. + * \param spec a Pointer to an SDL_AudioSpec that will be set to the WAVE + * data's format details on successful return. + * \param audio_buf a Pointer filled with the audio data, allocated by the + * function. + * \param audio_len a Pointer filled with the length of the audio data buffer + * in bytes. + * \returns true on success. `audio_buf` will be filled with a Pointer to an + * allocated buffer containing the audio data, and `audio_len` is + * filled with the length of that audio buffer in bytes. + * + * This function returns false if the .WAV file cannot be opened, + * uses an unknown data format, or is corrupt; call SDL_GetError() + * for more information. + * + * When the application is done with the data returned in + * `audio_buf`, it should call SDL_free() to dispose of it. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_free + * \sa SDL_LoadWAV_IO + } +function SDL_LoadWAV(path: PAnsiChar; spec: PSDL_AudioSpec; audio_buf: ppcuint8; audio_len: pcuint32): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_LoadWAV' {$ENDIF} {$ENDIF}; + +{* + * Mix audio data in a specified format. + * + * This takes an audio buffer `src` of `len` bytes of `format` data and mixes + * it into `dst`, performing addition, volume adjustment, and overflow + * clipping. The buffer pointed to by `dst` must also be `len` bytes of + * `format` data. + * + * This is provided for convenience -- you can mix your own audio data. + * + * Do not use this function for mixing together more than two streams of + * sample data. The output from repeated application of this function may be + * distorted by clipping, because there is no accumulator with greater range + * than the input (not to mention this being an inefficient way of doing it). + * + * It is a common misconception that this function is required to write audio + * data to an output stream in an audio callback. While you can do that, + * SDL_MixAudio() is really only needed when you're mixing a single audio + * stream with a volume adjustment. + * + * \param dst the destination for the mixed audio. + * \param src the source audio buffer to be mixed. + * \param format the SDL_AudioFormat structure representing the desired audio + * format. + * \param len the length of the audio buffer in bytes. + * \param volume ranges from 0.0 - 1.0, and should be set to 1.0 for full + * audio volume. + * \returns true on success or false on failure; call SDL_GetError() for more + * information. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + } +function SDL_MixAudio(dst: pcuint8; src: pcuint8; format: TSDL_AudioFormat; len: cuint32; volume: cfloat): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_MixAudio' {$ENDIF} {$ENDIF}; + +{* + * Convert some audio data of one format to another format. + * + * Please note that this function is for convenience, but should not be used + * to resample audio in blocks, as it will introduce audio artifacts on the + * boundaries. You should only use this function if you are converting audio + * data in its entirety in one call. If you want to convert audio in smaller + * chunks, use an SDL_AudioStream, which is designed for this situation. + * + * Internally, this function creates and destroys an SDL_AudioStream on each + * use, so it's also less efficient than using one directly, if you need to + * convert multiple times. + * + * \param src_spec the format details of the input audio. + * \param src_data the audio data to be converted. + * \param src_len the len of src_data. + * \param dst_spec the format details of the output audio. + * \param dst_data will be filled with a Pointer to converted audio data, + * which should be freed with SDL_free(). On error, it will be + * nil. + * \param dst_len will be filled with the len of dst_data. + * \returns true on success or false on failure; call SDL_GetError() for more + * information. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + } +function SDL_ConvertAudioSamples(src_spec: PSDL_AudioSpec; src_data: pcuint8; src_len: cint; dst_spec: PSDL_AudioSpec; dst_data: ppcuint8; dst_len: pcint): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_ConvertAudioSamples' {$ENDIF} {$ENDIF}; + +{* + * Get the human readable name of an audio format. + * + * \param format the audio format to query. + * \returns the human readable name of the specified audio format or + * "SDL_AUDIO_UNKNOWN" if the format isn't recognized. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + } +function SDL_GetAudioFormatName(format: TSDL_AudioFormat): PAnsiChar; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetAudioFormatName' {$ENDIF} {$ENDIF}; + +{* + * Get the appropriate memset value for silencing an audio format. + * + * The value returned by this function can be used as the second argument to + * memset (or SDL_memset) to set an audio buffer in a specific format to + * silence. + * + * \param format the audio data format to query. + * \returns a byte value that can be passed to memset. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + } +function SDL_GetSilenceValueForFormat(format: TSDL_AudioFormat): cint; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetSilenceValueForFormat' {$ENDIF} {$ENDIF}; + diff --git a/units/SDL_camera.inc b/units/SDL_camera.inc new file mode 100644 index 0000000..cf25445 --- /dev/null +++ b/units/SDL_camera.inc @@ -0,0 +1,473 @@ +{ + This file is part of: + + SDL3 for Pascal + (https://github.com/PascalGameDevelopment/SDL3-for-Pascal) + SPDX-License-Identifier: Zlib +} + +{* + * # CategoryCamera + * + * Video capture for the SDL library. + * + * This API lets apps read input from video sources, like webcams. Camera + * devices can be enumerated, queried, and opened. Once opened, it will + * provide SDL_Surface objects as new frames of video come in. These surfaces + * can be uploaded to an SDL_Texture or processed as pixels in memory. + } + +{* + * This is a unique ID for a camera device for the time it is connected to the + * system, and is never reused for the lifetime of the application. + * + * If the device is disconnected and reconnected, it will get a new ID. + * + * The value 0 is an invalid ID. + * + * \since This datatype is available since SDL 3.1.3. + * + * \sa SDL_GetCameras + } +type + PPSDL_CameraID = ^PSDL_CameraID; + PSDL_CameraID = ^TSDL_CameraID; + TSDL_CameraID = cuint32; + +{* + * The opaque structure used to identify an opened SDL camera. + * + * \since This struct is available since SDL 3.1.3. + } +type + PPSDL_Camera = ^PSDL_Camera; + PSDL_Camera = type Pointer; + +{* + * The details of an output format for a camera device. + * + * Cameras often support multiple formats; each one will be encapsulated in + * this struct. + * + * \since This struct is available since SDL 3.1.3. + * + * \sa SDL_GetCameraSupportedFormats + * \sa SDL_GetCameraFormat + } +type + PPSDL_CameraSpec = ^PSDL_CameraSpec; + PSDL_CameraSpec = ^TSDL_CameraSpec; + TSDL_CameraSpec = record + format: TSDL_PixelFormat; {*< Frame format } + colorspace: TSDL_Colorspace; {*< Frame colorspace } + width: cint; {*< Frame width } + height: cint; {*< Frame height } + framerate_numerator: cint; {*< Frame rate numerator ((num / denom) == FPS, (denom / num) == duration in seconds) } + framerate_denominator: cint; {*< Frame rate demoninator ((num / denom) == FPS, (denom / num) == duration in seconds) } + end; + +{* + * The position of camera in relation to system device. + * + * \since This enum is available since SDL 3.1.3. + * + * \sa SDL_GetCameraPosition + } +type + PPSDL_CameraPosition = ^PSDL_CameraPosition; + PSDL_CameraPosition = ^TSDL_CameraPosition; + TSDL_CameraPosition = Integer; +const + SDL_CAMERA_POSITION_UNKNOWN = TSDL_CameraPosition(0); + SDL_CAMERA_POSITION_FRONT_FACING = TSDL_CameraPosition(1); + SDL_CAMERA_POSITION_BACK_FACING = TSDL_CameraPosition(2); + +{* + * Use this function to get the number of built-in camera drivers. + * + * This function returns a hardcoded number. This never returns a negative + * value; if there are no drivers compiled into this build of SDL, this + * function returns zero. The presence of a driver in this list does not mean + * it will function, it just means SDL is capable of interacting with that + * interface. For example, a build of SDL might have v4l2 support, but if + * there's no kernel support available, SDL's v4l2 driver would fail if used. + * + * By default, SDL tries all drivers, in its preferred order, until one is + * found to be usable. + * + * \returns the number of built-in camera drivers. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetCameraDriver + } +function SDL_GetNumCameraDrivers: cint; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetNumCameraDrivers' {$ENDIF} {$ENDIF}; + +{* + * Use this function to get the name of a built in camera driver. + * + * The list of camera drivers is given in the order that they are normally + * initialized by default; the drivers that seem more reasonable to choose + * first (as far as the SDL developers believe) are earlier in the list. + * + * The names of drivers are all simple, low-ASCII identifiers, like "v4l2", + * "coremedia" or "android". These never have Unicode characters, and are not + * meant to be proper names. + * + * \param index the index of the camera driver; the value ranges from 0 to + * SDL_GetNumCameraDrivers() - 1. + * \returns the name of the camera driver at the requested index, or nil if + * an invalid index was specified. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetNumCameraDrivers + } +function SDL_GetCameraDriver(index: cint): PAnsiChar; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetCameraDriver' {$ENDIF} {$ENDIF}; + +{* + * Get the name of the current camera driver. + * + * The names of drivers are all simple, low-ASCII identifiers, like "v4l2", + * "coremedia" or "android". These never have Unicode characters, and are not + * meant to be proper names. + * + * \returns the name of the current camera driver or nil if no driver has + * been initialized. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + } +function SDL_GetCurrentCameraDriver: PAnsiChar; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetCurrentCameraDriver' {$ENDIF} {$ENDIF}; + +{* + * Get a list of currently connected camera devices. + * + * \param count a Pointer filled in with the number of cameras returned, may + * be nil. + * \returns a 0 terminated array of camera instance IDs or nil on failure; + * call SDL_GetError() for more information. This should be freed + * with SDL_free() when it is no longer needed. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_OpenCamera + } +function SDL_GetCameras(count: pcint): PSDL_CameraID; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetCameras' {$ENDIF} {$ENDIF}; + +{* + * Get the list of native formats/sizes a camera supports. + * + * This returns a list of all formats and frame sizes that a specific camera + * can offer. This is useful if your app can accept a variety of image formats + * and sizes and so want to find the optimal spec that doesn't require + * conversion. + * + * This function isn't strictly required; if you call SDL_OpenCamera with a + * nil spec, SDL will choose a native format for you, and if you instead + * specify a desired format, it will transparently convert to the requested + * format on your behalf. + * + * If `count` is not nil, it will be filled with the number of elements in + * the returned array. + * + * Note that it's legal for a camera to supply an empty list. This is what + * will happen on Emscripten builds, since that platform won't tell _anything_ + * about available cameras until you've opened one, and won't even tell if + * there _is_ a camera until the user has given you permission to check + * through a scary warning popup. + * + * \param devid the camera device instance ID to query. + * \param count a Pointer filled in with the number of elements in the list, + * may be nil. + * \returns a nil terminated array of pointers to SDL_CameraSpec or nil on + * failure; call SDL_GetError() for more information. This is a + * single allocation that should be freed with SDL_free() when it is + * no longer needed. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetCameras + * \sa SDL_OpenCamera + } +function SDL_GetCameraSupportedFormats(devid: TSDL_CameraID; count: pcint):PPSDL_CameraSpec; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetCameraSupportedFormats' {$ENDIF} {$ENDIF}; + +{* + * Get the human-readable device name for a camera. + * + * \param instance_id the camera device instance ID. + * \returns a human-readable device name or nil on failure; call + * SDL_GetError() for more information. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetCameras + } +function SDL_GetCameraName(instance_id: TSDL_CameraID): PAnsiChar; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetCameraName' {$ENDIF} {$ENDIF}; + +{* + * Get the position of the camera in relation to the system. + * + * Most platforms will report UNKNOWN, but mobile devices, like phones, can + * often make a distinction between cameras on the front of the device (that + * points towards the user, for taking "selfies") and cameras on the back (for + * filming in the direction the user is facing). + * + * \param instance_id the camera device instance ID. + * \returns the position of the camera on the system hardware. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetCameras + } +function SDL_GetCameraPosition(instance_id: TSDL_CameraID): TSDL_CameraPosition; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetCameraPosition' {$ENDIF} {$ENDIF}; + +{* + * Open a video recording device (a "camera"). + * + * You can open the device with any reasonable spec, and if the hardware can't + * directly support it, it will convert data seamlessly to the requested + * format. This might incur overhead, including scaling of image data. + * + * If you would rather accept whatever format the device offers, you can pass + * a nil spec here and it will choose one for you (and you can use + * SDL_Surface's conversion/scaling functions directly if necessary). + * + * You can call SDL_GetCameraFormat() to get the actual data format if passing + * a nil spec here. You can see the exact specs a device can support without + * conversion with SDL_GetCameraSupportedFormats(). + * + * SDL will not attempt to emulate framerate; it will try to set the hardware + * to the rate closest to the requested speed, but it won't attempt to limit + * or duplicate frames artificially; call SDL_GetCameraFormat() to see the + * actual framerate of the opened the device, and check your timestamps if + * this is crucial to your app! + * + * Note that the camera is not usable until the user approves its use! On some + * platforms, the operating system will prompt the user to permit access to + * the camera, and they can choose Yes or No at that point. Until they do, the + * camera will not be usable. The app should either wait for an + * SDL_EVENT_CAMERA_DEVICE_APPROVED (or SDL_EVENT_CAMERA_DEVICE_DENIED) event, + * or poll SDL_GetCameraPermissionState() occasionally until it returns + * non-zero. On platforms that don't require explicit user approval (and + * perhaps in places where the user previously permitted access), the approval + * event might come immediately, but it might come seconds, minutes, or hours + * later! + * + * \param instance_id the camera device instance ID. + * \param spec the desired format for data the device will provide. Can be + * nil. + * \returns an SDL_Camera object or nil on failure; call SDL_GetError() for + * more information. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetCameras + * \sa SDL_GetCameraFormat + } +function SDL_OpenCamera(instance_id: TSDL_CameraID; spec: PSDL_CameraSpec): PSDL_Camera; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_OpenCamera' {$ENDIF} {$ENDIF}; + +{* + * Query if camera access has been approved by the user. + * + * Cameras will not function between when the device is opened by the app and + * when the user permits access to the hardware. On some platforms, this + * presents as a popup dialog where the user has to explicitly approve access; + * on others the approval might be implicit and not alert the user at all. + * + * This function can be used to check the status of that approval. It will + * return 0 if still waiting for user response, 1 if the camera is approved + * for use, and -1 if the user denied access. + * + * Instead of polling with this function, you can wait for a + * SDL_EVENT_CAMERA_DEVICE_APPROVED (or SDL_EVENT_CAMERA_DEVICE_DENIED) event + * in the standard SDL event loop, which is guaranteed to be sent once when + * permission to use the camera is decided. + * + * If a camera is declined, there's nothing to be done but call + * SDL_CloseCamera() to dispose of it. + * + * \param camera the opened camera device to query. + * \returns -1 if user denied access to the camera, 1 if user approved access, + * 0 if no decision has been made yet. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_OpenCamera + * \sa SDL_CloseCamera + } +function SDL_GetCameraPermissionState(camera: PSDL_Camera): cint; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetCameraPermissionState' {$ENDIF} {$ENDIF}; + +{* + * Get the instance ID of an opened camera. + * + * \param camera an SDL_Camera to query. + * \returns the instance ID of the specified camera on success or 0 on + * failure; call SDL_GetError() for more information. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_OpenCamera + } +function SDL_GetCameraID(camera: PSDL_Camera): TSDL_CameraID; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetCameraID' {$ENDIF} {$ENDIF}; + +{* + * Get the properties associated with an opened camera. + * + * \param camera the SDL_Camera obtained from SDL_OpenCamera(). + * \returns a valid property ID on success or 0 on failure; call + * SDL_GetError() for more information. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + } +function SDL_GetCameraProperties(camera: PSDL_Camera): TSDL_PropertiesID; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetCameraProperties' {$ENDIF} {$ENDIF}; + +{* + * Get the spec that a camera is using when generating images. + * + * Note that this might not be the native format of the hardware, as SDL might + * be converting to this format behind the scenes. + * + * If the system is waiting for the user to approve access to the camera, as + * some platforms require, this will return false, but this isn't necessarily + * a fatal error; you should either wait for an + * SDL_EVENT_CAMERA_DEVICE_APPROVED (or SDL_EVENT_CAMERA_DEVICE_DENIED) event, + * or poll SDL_GetCameraPermissionState() occasionally until it returns + * non-zero. + * + * \param camera opened camera device. + * \param spec the SDL_CameraSpec to be initialized by this function. + * \returns true on success or false on failure; call SDL_GetError() for more + * information. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_OpenCamera + } +function SDL_GetCameraFormat(camera: PSDL_Camera; spec: PSDL_CameraSpec): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetCameraFormat' {$ENDIF} {$ENDIF}; + +{* + * Acquire a frame. + * + * The frame is a memory Pointer to the image data, whose size and format are + * given by the spec requested when opening the device. + * + * This is a non blocking API. If there is a frame available, a non-nil + * surface is returned, and timestampNS will be filled with a non-zero value. + * + * Note that an error case can also return nil, but a nil by itself is + * normal and just signifies that a new frame is not yet available. Note that + * even if a camera device fails outright (a USB camera is unplugged while in + * use, etc), SDL will send an event separately to notify the app, but + * continue to provide blank frames at ongoing intervals until + * SDL_CloseCamera() is called, so real failure here is almost always an out + * of memory condition. + * + * After use, the frame should be released with SDL_ReleaseCameraFrame(). If + * you don't do this, the system may stop providing more video! + * + * Do not call SDL_FreeSurface() on the returned surface! It must be given + * back to the camera subsystem with SDL_ReleaseCameraFrame! + * + * If the system is waiting for the user to approve access to the camera, as + * some platforms require, this will return nil (no frames available); you + * should either wait for an SDL_EVENT_CAMERA_DEVICE_APPROVED (or + * SDL_EVENT_CAMERA_DEVICE_DENIED) event, or poll + * SDL_GetCameraPermissionState() occasionally until it returns non-zero. + * + * \param camera opened camera device. + * \param timestampNS a Pointer filled in with the frame's timestamp, or 0 on + * error. Can be nil. + * \returns a new frame of video on success, nil if none is currently + * available. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_ReleaseCameraFrame + } +function SDL_AcquireCameraFrame(camera: PSDL_Camera; timestampNS: pcuint64): PSDL_Surface; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_AcquireCameraFrame' {$ENDIF} {$ENDIF}; + +{* + * Release a frame of video acquired from a camera. + * + * Let the back-end re-use the internal buffer for camera. + * + * This function _must_ be called only on surface objects returned by + * SDL_AcquireCameraFrame(). This function should be called as quickly as + * possible after acquisition, as SDL keeps a small FIFO queue of surfaces for + * video frames; if surfaces aren't released in a timely manner, SDL may drop + * upcoming video frames from the camera. + * + * If the app needs to keep the surface for a significant time, they should + * make a copy of it and release the original. + * + * The app should not use the surface again after calling this function; + * assume the surface is freed and the Pointer is invalid. + * + * \param camera opened camera device. + * \param frame the video frame surface to release. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_AcquireCameraFrame + } +procedure SDL_ReleaseCameraFrame(camera: PSDL_Camera; frame: PSDL_Surface); cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_ReleaseCameraFrame' {$ENDIF} {$ENDIF}; + +{* + * Use this function to shut down camera processing and close the camera + * device. + * + * \param camera opened camera device. + * + * \threadsafety It is safe to call this function from any thread, but no + * thread may reference `device` once this function is called. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_OpenCameraWithSpec + * \sa SDL_OpenCamera + } +procedure SDL_CloseCamera(camera: PSDL_Camera); cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_CloseCamera' {$ENDIF} {$ENDIF}; + diff --git a/units/SDL_events.inc b/units/SDL_events.inc new file mode 100644 index 0000000..83702bd --- /dev/null +++ b/units/SDL_events.inc @@ -0,0 +1,1556 @@ +{ + This file is part of: + + SDL3 for Pascal + (https://github.com/PascalGameDevelopment/SDL3-for-Pascal) + SPDX-License-Identifier: Zlib +} + +{* + * # CategoryEvents + * + * Event queue management. + } + +{ General keyboard/mouse/pen state definitions } + +{* + * The types of events that can be delivered. + * + * \since This enum is available since SDL 3.1.3. + } +type + PPSDL_EventType = ^PSDL_EventType; + PSDL_EventType = ^TSDL_EventType; + TSDL_EventType = type Integer; +const + SDL_EVENT_FIRST = 0; {*< Unused (do not remove) } + + { Application events } {*< User-requested quit } + SDL_EVENT_QUIT = TSDL_EventType($100); + + { These application events have special meaning on iOS and Android, see README-ios.md and README-android.md for details } + SDL_EVENT_TERMINATING = TSDL_EventType(257); {*< The application is being terminated by the OS. This event must be handled in a callback set with SDL_AddEventWatch(). + Called on iOS in applicationWillTerminate() + Called on Android in onDestroy() + } + SDL_EVENT_LOW_MEMORY = TSDL_EventType(258); {*< The application is low on memory, free memory if possible. This event must be handled in a callback set with SDL_AddEventWatch(). + Called on iOS in applicationDidReceiveMemoryWarning() + Called on Android in onTrimMemory() + } + SDL_EVENT_WILL_ENTER_BACKGROUND = TSDL_EventType(259); {*< The application is about to enter the background. This event must be handled in a callback set with SDL_AddEventWatch(). + Called on iOS in applicationWillResignActive() + Called on Android in onPause() + } + SDL_EVENT_DID_ENTER_BACKGROUND = TSDL_EventType(260); {*< The application did enter the background and may not get CPU for some time. This event must be handled in a callback set with SDL_AddEventWatch(). + Called on iOS in applicationDidEnterBackground() + Called on Android in onPause() + } + SDL_EVENT_WILL_ENTER_FOREGROUND = TSDL_EventType(261); {*< The application is about to enter the foreground. This event must be handled in a callback set with SDL_AddEventWatch(). + Called on iOS in applicationWillEnterForeground() + Called on Android in onResume() + } + SDL_EVENT_DID_ENTER_FOREGROUND = TSDL_EventType(262); {*< The application is now interactive. This event must be handled in a callback set with SDL_AddEventWatch(). + Called on iOS in applicationDidBecomeActive() + Called on Android in onResume() + } + + SDL_EVENT_LOCALE_CHANGED = TSDL_EventType(263); {*< The user's locale preferences have changed. } + + SDL_EVENT_SYSTEM_THEME_CHANGED = TSDL_EventType(264); {*< The system theme changed } + + { Display events } + { 0x150 was SDL_DISPLAYEVENT, reserve the number for sdl2-compat } + SDL_EVENT_DISPLAY_ORIENTATION = TSDL_EventType($151); {*< Display orientation has changed to data1 } + SDL_EVENT_DISPLAY_ADDED = TSDL_EventType(338); {*< Display has been added to the system } + SDL_EVENT_DISPLAY_REMOVED = TSDL_EventType(339); {*< Display has been removed from the system } + SDL_EVENT_DISPLAY_MOVED = TSDL_EventType(340); {*< Display has changed position } + SDL_EVENT_DISPLAY_DESKTOP_MODE_CHANGED = TSDL_EventType(341); {*< Display has changed desktop mode } + SDL_EVENT_DISPLAY_CURRENT_MODE_CHANGED = TSDL_EventType(342); {*< Display has changed current mode } + SDL_EVENT_DISPLAY_CONTENT_SCALE_CHANGED = TSDL_EventType(343); {*< Display has changed content scale } + SDL_EVENT_DISPLAY_FIRST = TSDL_EventType(SDL_EVENT_DISPLAY_ORIENTATION); + SDL_EVENT_DISPLAY_LAST = TSDL_EventType(SDL_EVENT_DISPLAY_CONTENT_SCALE_CHANGED); + + { Window events } + { 0x200 was SDL_WINDOWEVENT, reserve the number for sdl2-compat } + { 0x201 was SDL_EVENT_SYSWM, reserve the number for sdl2-compat } + SDL_EVENT_WINDOW_SHOWN = TSDL_EventType($202); {*< Window has been shown } + SDL_EVENT_WINDOW_HIDDEN = TSDL_EventType(515); {*< Window has been hidden } + SDL_EVENT_WINDOW_EXPOSED = TSDL_EventType(516); {*< Window has been exposed and should be redrawn, and can be redrawn directly from event watchers for this event } + SDL_EVENT_WINDOW_MOVED = TSDL_EventType(517); {*< Window has been moved to data1, data2 } + SDL_EVENT_WINDOW_RESIZED = TSDL_EventType(518); {*< Window has been resized to data1xdata2 } + SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED = TSDL_EventType(519); {*< The pixel size of the window has changed to data1xdata2 } + SDL_EVENT_WINDOW_METAL_VIEW_RESIZED = TSDL_EventType(520); {*< The pixel size of a Metal view associated with the window has changed } + SDL_EVENT_WINDOW_MINIMIZED = TSDL_EventType(521); {*< Window has been minimized } + SDL_EVENT_WINDOW_MAXIMIZED = TSDL_EventType(522); {*< Window has been maximized } + SDL_EVENT_WINDOW_RESTORED = TSDL_EventType(523); {*< Window has been restored to normal size and position } + SDL_EVENT_WINDOW_MOUSE_ENTER = TSDL_EventType(524); {*< Window has gained mouse focus } + SDL_EVENT_WINDOW_MOUSE_LEAVE = TSDL_EventType(525); {*< Window has lost mouse focus } + SDL_EVENT_WINDOW_FOCUS_GAINED = TSDL_EventType(526); {*< Window has gained keyboard focus } + SDL_EVENT_WINDOW_FOCUS_LOST = TSDL_EventType(527); {*< Window has lost keyboard focus } + SDL_EVENT_WINDOW_CLOSE_REQUESTED = TSDL_EventType(528); {*< The window manager requests that the window be closed } + SDL_EVENT_WINDOW_HIT_TEST = TSDL_EventType(529); {*< Window had a hit test that wasn't SDL_HITTEST_NORMAL } + SDL_EVENT_WINDOW_ICCPROF_CHANGED = TSDL_EventType(530); {*< The ICC profile of the window's display has changed } + SDL_EVENT_WINDOW_DISPLAY_CHANGED = TSDL_EventType(531); {*< Window has been moved to display data1 } + SDL_EVENT_WINDOW_DISPLAY_SCALE_CHANGED = TSDL_EventType(532); {*< Window display scale has been changed } + SDL_EVENT_WINDOW_SAFE_AREA_CHANGED = TSDL_EventType(533); {*< The window safe area has been changed } + SDL_EVENT_WINDOW_OCCLUDED = TSDL_EventType(534); {*< The window has been occluded } + SDL_EVENT_WINDOW_ENTER_FULLSCREEN = TSDL_EventType(535); {*< The window has entered fullscreen mode } + SDL_EVENT_WINDOW_LEAVE_FULLSCREEN = TSDL_EventType(536); {*< The window has left fullscreen mode } + SDL_EVENT_WINDOW_DESTROYED = TSDL_EventType(537); {*< The window with the associated ID is being or has been destroyed. If this message is being handled + in an event watcher, the window handle is still valid and can still be used to retrieve any properties + associated with the window. Otherwise, the handle has already been destroyed and all resources + associated with it are invalid } + SDL_EVENT_WINDOW_HDR_STATE_CHANGED = TSDL_EventType(538); {*< Window HDR properties have changed } + SDL_EVENT_WINDOW_FIRST = TSDL_EventType(SDL_EVENT_WINDOW_SHOWN); + SDL_EVENT_WINDOW_LAST = TSDL_EventType(SDL_EVENT_WINDOW_HDR_STATE_CHANGED); + + { Keyboard events } + SDL_EVENT_KEY_DOWN = TSDL_EventType($300); {*< Key pressed } + SDL_EVENT_KEY_UP = TSDL_EventType(769); {*< Key released } + SDL_EVENT_TEXT_EDITING = TSDL_EventType(770); {*< Keyboard text editing (composition) } + SDL_EVENT_TEXT_INPUT = TSDL_EventType(771); {*< Keyboard text input } + SDL_EVENT_KEYMAP_CHANGED = TSDL_EventType(772); {*< Keymap changed due to a system event such as an + input language or keyboard layout change. } + SDL_EVENT_KEYBOARD_ADDED = TSDL_EventType(773); {*< A new keyboard has been inserted into the system } + SDL_EVENT_KEYBOARD_REMOVED = TSDL_EventType(774); {*< A keyboard has been removed } + SDL_EVENT_TEXT_EDITING_CANDIDATES = TSDL_EventType(775); {*< Keyboard text editing candidates } + + { Mouse events } + SDL_EVENT_MOUSE_MOTION = TSDL_EventType($400); {*< Mouse moved } + SDL_EVENT_MOUSE_BUTTON_DOWN = TSDL_EventType(1025); {*< Mouse button pressed } + SDL_EVENT_MOUSE_BUTTON_UP = TSDL_EventType(1026); {*< Mouse button released } + SDL_EVENT_MOUSE_WHEEL = TSDL_EventType(1027); {*< Mouse wheel motion } + SDL_EVENT_MOUSE_ADDED = TSDL_EventType(1028); {*< A new mouse has been inserted into the system } + SDL_EVENT_MOUSE_REMOVED = TSDL_EventType(1029); {*< A mouse has been removed } + + { Joystick events } + SDL_EVENT_JOYSTICK_AXIS_MOTION = TSDL_EventType($600); {*< Joystick axis motion } + SDL_EVENT_JOYSTICK_BALL_MOTION = TSDL_EventType(1537); {*< Joystick trackball motion } + SDL_EVENT_JOYSTICK_HAT_MOTION = TSDL_EventType(1538); {*< Joystick hat position change } + SDL_EVENT_JOYSTICK_BUTTON_DOWN = TSDL_EventType(1539); {*< Joystick button pressed } + SDL_EVENT_JOYSTICK_BUTTON_UP = TSDL_EventType(1540); {*< Joystick button released } + SDL_EVENT_JOYSTICK_ADDED = TSDL_EventType(1541); {*< A new joystick has been inserted into the system } + SDL_EVENT_JOYSTICK_REMOVED = TSDL_EventType(1542); {*< An opened joystick has been removed } + SDL_EVENT_JOYSTICK_BATTERY_UPDATED = TSDL_EventType(1543); {*< Joystick battery level change } + SDL_EVENT_JOYSTICK_UPDATE_COMPLETE = TSDL_EventType(1544); {*< Joystick update is complete } + + { Gamepad events } + SDL_EVENT_GAMEPAD_AXIS_MOTION = TSDL_EventType($650); {*< Gamepad axis motion } + SDL_EVENT_GAMEPAD_BUTTON_DOWN = TSDL_EventType(1617); {*< Gamepad button pressed } + SDL_EVENT_GAMEPAD_BUTTON_UP = TSDL_EventType(1618); {*< Gamepad button released } + SDL_EVENT_GAMEPAD_ADDED = TSDL_EventType(1619); {*< A new gamepad has been inserted into the system } + SDL_EVENT_GAMEPAD_REMOVED = TSDL_EventType(1620); {*< A gamepad has been removed } + SDL_EVENT_GAMEPAD_REMAPPED = TSDL_EventType(1621); {*< The gamepad mapping was updated } + SDL_EVENT_GAMEPAD_TOUCHPAD_DOWN = TSDL_EventType(1622); {*< Gamepad touchpad was touched } + SDL_EVENT_GAMEPAD_TOUCHPAD_MOTION = TSDL_EventType(1623); {*< Gamepad touchpad finger was moved } + SDL_EVENT_GAMEPAD_TOUCHPAD_UP = TSDL_EventType(1624); {*< Gamepad touchpad finger was lifted } + SDL_EVENT_GAMEPAD_SENSOR_UPDATE = TSDL_EventType(1625); {*< Gamepad sensor was updated } + SDL_EVENT_GAMEPAD_UPDATE_COMPLETE = TSDL_EventType(1626); {*< Gamepad update is complete } + SDL_EVENT_GAMEPAD_STEAM_HANDLE_UPDATED = TSDL_EventType(1627); {*< Gamepad Steam handle has changed } + + { Touch events } + SDL_EVENT_FINGER_DOWN = TSDL_EventType($700); + SDL_EVENT_FINGER_UP = TSDL_EventType(1793); + SDL_EVENT_FINGER_MOTION = TSDL_EventType(1794); + + { 0x800, 0x801, and 0x802 were the Gesture events from SDL2. Do not reuse these values! sdl2-compat needs them! } + + { Clipboard events } + SDL_EVENT_CLIPBOARD_UPDATE = TSDL_EventType($900); {*< The clipboard or primary selection changed } + + { Drag and drop events } + SDL_EVENT_DROP_FILE = TSDL_EventType($1000); {*< The system requests a file open } + SDL_EVENT_DROP_TEXT = TSDL_EventType(4097); {*< text/plain drag-and-drop event } + SDL_EVENT_DROP_BEGIN = TSDL_EventType(4098); {*< A new set of drops is beginning (nil filename) } + SDL_EVENT_DROP_COMPLETE = TSDL_EventType(4099); {*< Current set of drops is now complete (nil filename) } + SDL_EVENT_DROP_POSITION = TSDL_EventType(4100); {*< Position while moving over the window } + + { Audio hotplug events } + SDL_EVENT_AUDIO_DEVICE_ADDED = TSDL_EventType($1100); {*< A new audio device is available } + SDL_EVENT_AUDIO_DEVICE_REMOVED = TSDL_EventType(4353); {*< An audio device has been removed. } + SDL_EVENT_AUDIO_DEVICE_FORMAT_CHANGED = TSDL_EventType(4354); {*< An audio device's format has been changed by the system. } + + { Sensor events } + SDL_EVENT_SENSOR_UPDATE = TSDL_EventType($1200); {*< A sensor was updated } + + { Pressure-sensitive pen events } + SDL_EVENT_PEN_PROXIMITY_IN = TSDL_EventType($1300); {*< Pressure-sensitive pen has become available } + SDL_EVENT_PEN_PROXIMITY_OUT = TSDL_EventType(4865); {*< Pressure-sensitive pen has become unavailable } + SDL_EVENT_PEN_DOWN = TSDL_EventType(4866); {*< Pressure-sensitive pen touched drawing surface } + SDL_EVENT_PEN_UP = TSDL_EventType(4867); {*< Pressure-sensitive pen stopped touching drawing surface } + SDL_EVENT_PEN_BUTTON_DOWN = TSDL_EventType(4868); {*< Pressure-sensitive pen button pressed } + SDL_EVENT_PEN_BUTTON_UP = TSDL_EventType(4869); {*< Pressure-sensitive pen button released } + SDL_EVENT_PEN_MOTION = TSDL_EventType(4870); {*< Pressure-sensitive pen is moving on the tablet } + SDL_EVENT_PEN_AXIS = TSDL_EventType(4871); {*< Pressure-sensitive pen angle/pressure/etc changed } + + { Camera hotplug events } + SDL_EVENT_CAMERA_DEVICE_ADDED = TSDL_EventType($1400); {*< A new camera device is available } + SDL_EVENT_CAMERA_DEVICE_REMOVED = TSDL_EventType(5121); {*< A camera device has been removed. } + SDL_EVENT_CAMERA_DEVICE_APPROVED = TSDL_EventType(5122); {*< A camera device has been approved for use by the user. } + SDL_EVENT_CAMERA_DEVICE_DENIED = TSDL_EventType(5123); {*< A camera device has been denied for use by the user. } + + { Render events } + SDL_EVENT_RENDER_TARGETS_RESET = TSDL_EventType($2000); {*< The render targets have been reset and their contents need to be updated } + SDL_EVENT_RENDER_DEVICE_RESET = TSDL_EventType(8193); {*< The device has been reset and all textures need to be recreated } + SDL_EVENT_RENDER_DEVICE_LOST = TSDL_EventType(8194); {*< The device has been lost and can't be recovered. } + + { Reserved events for private platforms } + SDL_EVENT_PRIVATE0 = TSDL_EventType($4000); + SDL_EVENT_PRIVATE1 = TSDL_EventType(16385); + SDL_EVENT_PRIVATE2 = TSDL_EventType(16386); + SDL_EVENT_PRIVATE3 = TSDL_EventType(16387); + + { Internal events } + SDL_EVENT_POLL_SENTINEL = TSDL_EventType($7F00); {*< Signals the end of an event poll cycle } + + {* Events SDL_EVENT_USER through SDL_EVENT_LAST are for your use, + * and should be allocated with SDL_RegisterEvents() + } + SDL_EVENT_USER = TSDL_EventType($8000); + + {* + * This last event is only for bounding internal arrays + } + SDL_EVENT_LAST = TSDL_EventType($FFFF); + + { This just makes sure the enum is the size of Uint32 } + SDL_EVENT_ENUM_PADDING = TSDL_EventType($7FFFFFFF); + +{* + * Fields shared by every event + * + * \since This struct is available since SDL 3.1.3. + } +type + PPSDL_CommonEvent = ^PSDL_CommonEvent; + PSDL_CommonEvent = ^TSDL_CommonEvent; + TSDL_CommonEvent = record + type_: cuint32; {*< Event type, shared with all events, Uint32 to cover user events which are not in the SDL_EventType enumeration } + reserved: cuint32; + timestamp: cuint64; {*< In nanoseconds, populated using SDL_GetTicksNS() } + end; + +{* + * Display state change event data (event.display.*) + * + * \since This struct is available since SDL 3.1.3. + } + PPSDL_DisplayEvent = ^PSDL_DisplayEvent; + PSDL_DisplayEvent = ^TSDL_DisplayEvent; + TSDL_DisplayEvent = record + type_: TSDL_EventType; {*< SDL_DISPLAYEVENT_* } + reserved: cuint32; + timestamp: cuint64; {*< In nanoseconds, populated using SDL_GetTicksNS() } + displayID: TSDL_DisplayID; {*< The associated display } + data1: cint32; {*< event dependent data } + data2: cint32; {*< event dependent data } + end; + +{* + * Window state change event data (event.window.*) + * + * \since This struct is available since SDL 3.1.3. + } + PPSDL_WindowEvent = ^PSDL_WindowEvent; + PSDL_WindowEvent = ^TSDL_WindowEvent; + TSDL_WindowEvent = record + type_: TSDL_EventType; {*< SDL_EVENT_WINDOW_* } + reserved: cuint32; + timestamp: cuint64; {*< In nanoseconds, populated using SDL_GetTicksNS() } + windowID: TSDL_WindowID; {*< The associated window } + data1: cint32; {*< event dependent data } + data2: cint32; {*< event dependent data } + end; + +{* + * Keyboard device event structure (event.kdevice.*) + * + * \since This struct is available since SDL 3.1.3. + } + PPSDL_KeyboardDeviceEvent = ^PSDL_KeyboardDeviceEvent; + PSDL_KeyboardDeviceEvent = ^TSDL_KeyboardDeviceEvent; + TSDL_KeyboardDeviceEvent = record + type_: TSDL_EventType; {*< SDL_EVENT_KEYBOARD_ADDED or SDL_EVENT_KEYBOARD_REMOVED } + reserved: cuint32; + timestamp: cuint64; {*< In nanoseconds, populated using SDL_GetTicksNS() } + which: TSDL_KeyboardID; {*< The keyboard instance id } + end; + +{* + * Keyboard button event structure (event.key.*) + * + * The `key` is the base SDL_Keycode generated by pressing the `scancode` + * using the current keyboard layout, applying any options specified in + * SDL_HINT_KEYCODE_OPTIONS. You can get the SDL_Keycode corresponding to the + * event scancode and modifiers directly from the keyboard layout, bypassing + * SDL_HINT_KEYCODE_OPTIONS, by calling SDL_GetKeyFromScancode(). + * + * \since This struct is available since SDL 3.1.3. + * + * \sa SDL_GetKeyFromScancode + * \sa SDL_HINT_KEYCODE_OPTIONS + } + PPSDL_KeyboardEvent = ^PSDL_KeyboardEvent; + PSDL_KeyboardEvent = ^TSDL_KeyboardEvent; + TSDL_KeyboardEvent = record + type_: TSDL_EventType; {*< SDL_EVENT_KEY_DOWN or SDL_EVENT_KEY_UP } + reserved: cuint32; + timestamp: cuint64; {*< In nanoseconds, populated using SDL_GetTicksNS() } + windowID: TSDL_WindowID; {*< The window with keyboard focus, if any } + which: TSDL_KeyboardID; {*< The keyboard instance id, or 0 if unknown or virtual } + scancode: TSDL_Scancode; {*< SDL physical key code } + key: TSDL_Keycode; {*< SDL virtual key code } + mod_: TSDL_Keymod; {*< current key modifiers } + raw: cuint16; {*< The platform dependent scancode for this event } + down: cbool; {*< true if the key is pressed } + repeat_: cbool; {*< true if this is a key repeat } + end; + +{* + * Keyboard text editing event structure (event.edit.*) + * + * The start cursor is the position, in UTF-8 characters, where new typing + * will be inserted into the editing text. The length is the number of UTF-8 + * characters that will be replaced by new typing. + * + * \since This struct is available since SDL 3.1.3. + } + PPSDL_TextEditingEvent = ^PSDL_TextEditingEvent; + PSDL_TextEditingEvent = ^TSDL_TextEditingEvent; + TSDL_TextEditingEvent = record + type_: TSDL_EventType; {*< SDL_EVENT_TEXT_EDITING } + reserved: cuint32; + timestamp: cuint64; {*< In nanoseconds, populated using SDL_GetTicksNS() } + windowID: TSDL_WindowID; {*< The window with keyboard focus, if any } + text: PAnsiChar; {*< The editing text } + start: cint32; {*< The start cursor of selected editing text, or -1 if not set } + length: cint32; {*< The length of selected editing text, or -1 if not set } + end; + +{* + * Keyboard IME candidates event structure (event.edit_candidates.*) + * + * \since This struct is available since SDL 3.1.3. + } + PPSDL_TextEditingCandidatesEvent = ^PSDL_TextEditingCandidatesEvent; + PSDL_TextEditingCandidatesEvent = ^TSDL_TextEditingCandidatesEvent; + TSDL_TextEditingCandidatesEvent = record + type_: TSDL_EventType; {*< SDL_EVENT_TEXT_EDITING_CANDIDATES } + reserved: cuint32; + timestamp: cuint64; {*< In nanoseconds, populated using SDL_GetTicksNS() } + windowID: TSDL_WindowID; {*< The window with keyboard focus, if any } + candidates: ^PAnsiChar; {*< The list of candidates, or nil if there are no candidates available } + num_candidates: cint32; {*< The number of strings in `candidates` } + selected_candidate: cint32; {*< The index of the selected candidate, or -1 if no candidate is selected } + horizontal: cbool; {*< true if the list is horizontal, false if it's vertical } + padding1: cuint8; + padding2: cuint8; + padding3: cuint8; + end; + +{* + * Keyboard text input event structure (event.text.*) + * + * This event will never be delivered unless text input is enabled by calling + * SDL_StartTextInput(). Text input is disabled by default! + * + * \since This struct is available since SDL 3.1.3. + * + * \sa SDL_StartTextInput + * \sa SDL_StopTextInput + } + PPSDL_TextInputEvent = ^PSDL_TextInputEvent; + PSDL_TextInputEvent = ^TSDL_TextInputEvent; + TSDL_TextInputEvent = record + type_: TSDL_EventType; {*< SDL_EVENT_TEXT_INPUT } + reserved: cuint32; + timestamp: cuint64; {*< In nanoseconds, populated using SDL_GetTicksNS() } + windowID: TSDL_WindowID; {*< The window with keyboard focus, if any } + text: PAnsiChar; {*< The input text, UTF-8 encoded } + end; + +{* + * Mouse device event structure (event.mdevice.*) + * + * \since This struct is available since SDL 3.1.3. + } + PPSDL_MouseDeviceEvent = ^PSDL_MouseDeviceEvent; + PSDL_MouseDeviceEvent = ^TSDL_MouseDeviceEvent; + TSDL_MouseDeviceEvent = record + type_: TSDL_EventType; {*< SDL_EVENT_MOUSE_ADDED or SDL_EVENT_MOUSE_REMOVED } + reserved: cuint32; + timestamp: cuint64; {*< In nanoseconds, populated using SDL_GetTicksNS() } + which: TSDL_MouseID; {*< The mouse instance id } + end; + +{* + * Mouse motion event structure (event.motion.*) + * + * \since This struct is available since SDL 3.1.3. + } + PPSDL_MouseMotionEvent = ^PSDL_MouseMotionEvent; + PSDL_MouseMotionEvent = ^TSDL_MouseMotionEvent; + TSDL_MouseMotionEvent = record + type_: TSDL_EventType; {*< SDL_EVENT_MOUSE_MOTION } + reserved: cuint32; + timestamp: cuint64; {*< In nanoseconds, populated using SDL_GetTicksNS() } + windowID: TSDL_WindowID; {*< The window with mouse focus, if any } + which: TSDL_MouseID; {*< The mouse instance id or SDL_TOUCH_MOUSEID } + state: TSDL_MouseButtonFlags; {*< The current button state } + x: cfloat; {*< X coordinate, relative to window } + y: cfloat; {*< Y coordinate, relative to window } + xrel: cfloat; {*< The relative motion in the X direction } + yrel: cfloat; {*< The relative motion in the Y direction } + end; + +{* + * Mouse button event structure (event.button.*) + * + * \since This struct is available since SDL 3.1.3. + } + PPSDL_MouseButtonEvent = ^PSDL_MouseButtonEvent; + PSDL_MouseButtonEvent = ^TSDL_MouseButtonEvent; + TSDL_MouseButtonEvent = record + type_: TSDL_EventType; {*< SDL_EVENT_MOUSE_BUTTON_DOWN or SDL_EVENT_MOUSE_BUTTON_UP } + reserved: cuint32; + timestamp: cuint64; {*< In nanoseconds, populated using SDL_GetTicksNS() } + windowID: TSDL_WindowID; {*< The window with mouse focus, if any } + which: TSDL_MouseID; {*< The mouse instance id, SDL_TOUCH_MOUSEID } + button: cuint8; {*< The mouse button index } + down: cbool; {*< true if the button is pressed } + clicks: cuint8; {*< 1 for single-click, 2 for double-click, etc. } + padding: cuint8; + x: cfloat; {*< X coordinate, relative to window } + y: cfloat; {*< Y coordinate, relative to window } + end; + +{* + * Mouse wheel event structure (event.wheel.*) + * + * \since This struct is available since SDL 3.1.3. + } + PPSDL_MouseWheelEvent = ^PSDL_MouseWheelEvent; + PSDL_MouseWheelEvent = ^TSDL_MouseWheelEvent; + TSDL_MouseWheelEvent = record + type_: TSDL_EventType; {*< SDL_EVENT_MOUSE_WHEEL } + reserved: cuint32; + timestamp: cuint64; {*< In nanoseconds, populated using SDL_GetTicksNS() } + windowID: TSDL_WindowID; {*< The window with mouse focus, if any } + which: TSDL_MouseID; {*< The mouse instance id, SDL_TOUCH_MOUSEID } + x: cfloat; {*< The amount scrolled horizontally, positive to the right and negative to the left } + y: cfloat; {*< The amount scrolled vertically, positive away from the user and negative toward the user } + direction: TSDL_MouseWheelDirection; {*< Set to one of the SDL_MOUSEWHEEL_* defines. When FLIPPED the values in X and Y will be opposite. Multiply by -1 to change them back } + mouse_x: cfloat; {*< X coordinate, relative to window } + mouse_y: cfloat; {*< Y coordinate, relative to window } + end; + +{* + * Joystick axis motion event structure (event.jaxis.*) + * + * \since This struct is available since SDL 3.1.3. + } + PPSDL_JoyAxisEvent = ^PSDL_JoyAxisEvent; + PSDL_JoyAxisEvent = ^TSDL_JoyAxisEvent; + TSDL_JoyAxisEvent = record + type_: TSDL_EventType; {*< SDL_EVENT_JOYSTICK_AXIS_MOTION } + reserved: cuint32; + timestamp: cuint64; {*< In nanoseconds, populated using SDL_GetTicksNS() } + which: TSDL_JoystickID; {*< The joystick instance id } + axis: cuint8; {*< The joystick axis index } + padding1: cuint8; + padding2: cuint8; + padding3: cuint8; + value: cint16; {*< The axis value (range: -32768 to 32767) } + padding4: cuint16; + end; + +{* + * Joystick trackball motion event structure (event.jball.*) + * + * \since This struct is available since SDL 3.1.3. + } + PPSDL_JoyBallEvent = ^PSDL_JoyBallEvent; + PSDL_JoyBallEvent = ^TSDL_JoyBallEvent; + TSDL_JoyBallEvent = record + type_: TSDL_EventType; {*< SDL_EVENT_JOYSTICK_BALL_MOTION } + reserved: cuint32; + timestamp: cuint64; {*< In nanoseconds, populated using SDL_GetTicksNS() } + which: TSDL_JoystickID; {*< The joystick instance id } + ball: cuint8; {*< The joystick trackball index } + padding1: cuint8; + padding2: cuint8; + padding3: cuint8; + xrel: cint16; {*< The relative motion in the X direction } + yrel: cint16; {*< The relative motion in the Y direction } + end; + +{* + * Joystick hat position change event structure (event.jhat.*) + * + * \since This struct is available since SDL 3.1.3. + } + PPSDL_JoyHatEvent = ^PSDL_JoyHatEvent; + PSDL_JoyHatEvent = ^TSDL_JoyHatEvent; + TSDL_JoyHatEvent = record + type_: TSDL_EventType; {*< SDL_EVENT_JOYSTICK_HAT_MOTION } + reserved: cuint32; + timestamp: cuint64; {*< In nanoseconds, populated using SDL_GetTicksNS() } + which: TSDL_JoystickID; {*< The joystick instance id } + hat: cuint8; {*< The joystick hat index } + value: cuint8; {*< The hat position value. + * \sa SDL_HAT_LEFTUP SDL_HAT_UP SDL_HAT_RIGHTUP + * \sa SDL_HAT_LEFT SDL_HAT_CENTERED SDL_HAT_RIGHT + * \sa SDL_HAT_LEFTDOWN SDL_HAT_DOWN SDL_HAT_RIGHTDOWN + * + * Note that zero means the POV is centered. + } + padding1: cuint8; + padding2: cuint8; + end; +{* + * Joystick button event structure (event.jbutton.*) + * + * \since This struct is available since SDL 3.1.3. + } + PPSDL_JoyButtonEvent = ^PSDL_JoyButtonEvent; + PSDL_JoyButtonEvent = ^TSDL_JoyButtonEvent; + TSDL_JoyButtonEvent = record + type_: TSDL_EventType; {*< SDL_EVENT_JOYSTICK_BUTTON_DOWN or SDL_EVENT_JOYSTICK_BUTTON_UP } + reserved: cuint32; + timestamp: cuint64; {*< In nanoseconds, populated using SDL_GetTicksNS() } + which: TSDL_JoystickID; {*< The joystick instance id } + button: cuint8; {*< The joystick button index } + down: cbool; {*< true if the button is pressed } + padding1: cuint8; + padding2: cuint8; + end; + +{* + * Joystick device event structure (event.jdevice.*) + * + * SDL will send JOYSTICK_ADDED events for devices that are already plugged in + * during SDL_Init. + * + * \since This struct is available since SDL 3.1.3. + * + * \sa SDL_GamepadDeviceEvent + } + PPSDL_JoyDeviceEvent = ^PSDL_JoyDeviceEvent; + PSDL_JoyDeviceEvent = ^TSDL_JoyDeviceEvent; + TSDL_JoyDeviceEvent = record + type_: TSDL_EventType; {*< SDL_EVENT_JOYSTICK_ADDED or SDL_EVENT_JOYSTICK_REMOVED or SDL_EVENT_JOYSTICK_UPDATE_COMPLETE } + reserved: cuint32; + timestamp: cuint64; {*< In nanoseconds, populated using SDL_GetTicksNS() } + which: TSDL_JoystickID; {*< The joystick instance id } + end; + +{* + * Joystick battery level change event structure (event.jbattery.*) + * + * \since This struct is available since SDL 3.1.3. + } + PPSDL_JoyBatteryEvent = ^PSDL_JoyBatteryEvent; + PSDL_JoyBatteryEvent = ^TSDL_JoyBatteryEvent; + TSDL_JoyBatteryEvent = record + type_: TSDL_EventType; {*< SDL_EVENT_JOYSTICK_BATTERY_UPDATED } + reserved: cuint32; + timestamp: cuint64; {*< In nanoseconds, populated using SDL_GetTicksNS() } + which: TSDL_JoystickID; {*< The joystick instance id } + state: TSDL_PowerState; {*< The joystick battery state } + percent: cint; {*< The joystick battery percent charge remaining } + end; + +{* + * Gamepad axis motion event structure (event.gaxis.*) + * + * \since This struct is available since SDL 3.1.3. + } + PPSDL_GamepadAxisEvent = ^PSDL_GamepadAxisEvent; + PSDL_GamepadAxisEvent = ^TSDL_GamepadAxisEvent; + TSDL_GamepadAxisEvent = record + type_: TSDL_EventType; {*< SDL_EVENT_GAMEPAD_AXIS_MOTION } + reserved: cuint32; + timestamp: cuint64; {*< In nanoseconds, populated using SDL_GetTicksNS() } + which: TSDL_JoystickID; {*< The joystick instance id } + axis: cuint8; {*< The gamepad axis (SDL_GamepadAxis) } + padding1: cuint8; + padding2: cuint8; + padding3: cuint8; + value: cint16; {*< The axis value (range: -32768 to 32767) } + padding4: cuint16; + end; + +{* + * Gamepad button event structure (event.gbutton.*) + * + * \since This struct is available since SDL 3.1.3. + } + PPSDL_GamepadButtonEvent = ^PSDL_GamepadButtonEvent; + PSDL_GamepadButtonEvent = ^TSDL_GamepadButtonEvent; + TSDL_GamepadButtonEvent = record + type_: TSDL_EventType; {*< SDL_EVENT_GAMEPAD_BUTTON_DOWN or SDL_EVENT_GAMEPAD_BUTTON_UP } + reserved: cuint32; + timestamp: cuint64; {*< In nanoseconds, populated using SDL_GetTicksNS() } + which: TSDL_JoystickID; {*< The joystick instance id } + button: cuint8; {*< The gamepad button (SDL_GamepadButton) } + down: cbool; {*< true if the button is pressed } + padding1: cuint8; + padding2: cuint8; + end; + +{* + * Gamepad device event structure (event.gdevice.*) + * + * Joysticks that are supported gamepads receive both an SDL_JoyDeviceEvent + * and an SDL_GamepadDeviceEvent. + * + * SDL will send GAMEPAD_ADDED events for joysticks that are already plugged + * in during SDL_Init() and are recognized as gamepads. It will also send + * events for joysticks that get gamepad mappings at runtime. + * + * \since This struct is available since SDL 3.1.3. + * + * \sa SDL_JoyDeviceEvent + } + PPSDL_GamepadDeviceEvent = ^PSDL_GamepadDeviceEvent; + PSDL_GamepadDeviceEvent = ^TSDL_GamepadDeviceEvent; + TSDL_GamepadDeviceEvent = record + type_: TSDL_EventType; {*< SDL_EVENT_GAMEPAD_ADDED, SDL_EVENT_GAMEPAD_REMOVED, or SDL_EVENT_GAMEPAD_REMAPPED, SDL_EVENT_GAMEPAD_UPDATE_COMPLETE or SDL_EVENT_GAMEPAD_STEAM_HANDLE_UPDATED } + reserved: cuint32; + timestamp: cuint64; {*< In nanoseconds, populated using SDL_GetTicksNS() } + which: TSDL_JoystickID; {*< The joystick instance id } + end; + +{* + * Gamepad touchpad event structure (event.gtouchpad.*) + * + * \since This struct is available since SDL 3.1.3. + } + PPSDL_GamepadTouchpadEvent = ^PSDL_GamepadTouchpadEvent; + PSDL_GamepadTouchpadEvent = ^TSDL_GamepadTouchpadEvent; + TSDL_GamepadTouchpadEvent = record + type_: TSDL_EventType; {*< SDL_EVENT_GAMEPAD_TOUCHPAD_DOWN or SDL_EVENT_GAMEPAD_TOUCHPAD_MOTION or SDL_EVENT_GAMEPAD_TOUCHPAD_UP } + reserved: cuint32; + timestamp: cuint64; {*< In nanoseconds, populated using SDL_GetTicksNS() } + which: TSDL_JoystickID; {*< The joystick instance id } + touchpad: cint32; {*< The index of the touchpad } + finger: cint32; {*< The index of the finger on the touchpad } + x: cfloat; {*< Normalized in the range 0...1 with 0 being on the left } + y: cfloat; {*< Normalized in the range 0...1 with 0 being at the top } + pressure: cfloat; {*< Normalized in the range 0...1 } + end; + +{* + * Gamepad sensor event structure (event.gsensor.*) + * + * \since This struct is available since SDL 3.1.3. + } + PPSDL_GamepadSensorEvent = ^PSDL_GamepadSensorEvent; + PSDL_GamepadSensorEvent = ^TSDL_GamepadSensorEvent; + TSDL_GamepadSensorEvent = record + type_: TSDL_EventType; {*< SDL_EVENT_GAMEPAD_SENSOR_UPDATE } + reserved: cuint32; + timestamp: cuint64; {*< In nanoseconds, populated using SDL_GetTicksNS() } + which: TSDL_JoystickID; {*< The joystick instance id } + sensor: cint32; {*< The type of the sensor, one of the values of SDL_SensorType } + data: array[0..2] of cfloat; {*< Up to 3 values from the sensor, as defined in SDL_sensor.h } + sensor_timestamp: cuint64; {*< The timestamp of the sensor reading in nanoseconds, not necessarily synchronized with the system clock } + end; + +{* + * Audio device event structure (event.adevice.*) + * + * \since This struct is available since SDL 3.1.3. + } + PPSDL_AudioDeviceEvent = ^PSDL_AudioDeviceEvent; + PSDL_AudioDeviceEvent = ^TSDL_AudioDeviceEvent; + TSDL_AudioDeviceEvent = record + type_: TSDL_EventType; {*< SDL_EVENT_AUDIO_DEVICE_ADDED, or SDL_EVENT_AUDIO_DEVICE_REMOVED, or SDL_EVENT_AUDIO_DEVICE_FORMAT_CHANGED } + reserved: cuint32; + timestamp: cuint64; {*< In nanoseconds, populated using SDL_GetTicksNS() } + which: TSDL_AudioDeviceID; {*< SDL_AudioDeviceID for the device being added or removed or changing } + recording: cbool; {*< false if a playback device, true if a recording device. } + padding1: cuint8; + padding2: cuint8; + padding3: cuint8; + end; + +{* + * Camera device event structure (event.cdevice.*) + * + * \since This struct is available since SDL 3.1.3. + } + PPSDL_CameraDeviceEvent = ^PSDL_CameraDeviceEvent; + PSDL_CameraDeviceEvent = ^TSDL_CameraDeviceEvent; + TSDL_CameraDeviceEvent = record + type_: TSDL_EventType; {*< SDL_EVENT_CAMERA_DEVICE_ADDED, SDL_EVENT_CAMERA_DEVICE_REMOVED, SDL_EVENT_CAMERA_DEVICE_APPROVED, SDL_EVENT_CAMERA_DEVICE_DENIED } + reserved: cuint32; + timestamp: cuint64; {*< In nanoseconds, populated using SDL_GetTicksNS() } + which: TSDL_CameraID; {*< SDL_CameraID for the device being added or removed or changing } + end; + +{* + * Touch finger event structure (event.tfinger.*) + * + * Coordinates in this event are normalized. `x` and `y` are normalized to a + * range between 0.0f and 1.0f, relative to the window, so (0,0) is the top + * left and (1,1) is the bottom right. Delta coordinates `dx` and `dy` are + * normalized in the ranges of -1.0f (traversed all the way from the bottom or + * right to all the way up or left) to 1.0f (traversed all the way from the + * top or left to all the way down or right). + * + * Note that while the coordinates are _normalized_, they are not _clamped_, + * which means in some circumstances you can get a value outside of this + * range. For example, a renderer using logical presentation might give a + * negative value when the touch is in the letterboxing. Some platforms might + * report a touch outside of the window, which will also be outside of the + * range. + * + * \since This struct is available since SDL 3.1.3. + } + PPSDL_TouchFingerEvent = ^PSDL_TouchFingerEvent; + PSDL_TouchFingerEvent = ^TSDL_TouchFingerEvent; + TSDL_TouchFingerEvent = record + type_: TSDL_EventType; {*< SDL_EVENT_FINGER_MOTION or SDL_EVENT_FINGER_DOWN or SDL_EVENT_FINGER_UP } + reserved: cuint32; + timestamp: cuint64; {*< In nanoseconds, populated using SDL_GetTicksNS() } + touchID: TSDL_TouchID; {*< The touch device id } + fingerID: TSDL_FingerID; {*< Normalized in the range 0...1 } + x: cfloat; {*< Normalized in the range 0...1 } + y: cfloat; {*< Normalized in the range -1...1 } + dx: cfloat; {*< Normalized in the range -1...1 } + dy: cfloat; {*< Normalized in the range 0...1 } + pressure: cfloat; {*< The window underneath the finger, if any } + windowID: TSDL_WindowID; + end; + +{* + * Pressure-sensitive pen proximity event structure (event.pmotion.*) + * + * When a pen becomes visible to the system (it is close enough to a tablet, + * etc), SDL will send an SDL_EVENT_PEN_PROXIMITY_IN event with the new pen's + * ID. This ID is valid until the pen leaves proximity again (has been removed + * from the tablet's area, the tablet has been unplugged, etc). If the same + * pen reenters proximity again, it will be given a new ID. + * + * Note that "proximity" means "close enough for the tablet to know the tool + * is there." The pen touching and lifting off from the tablet while not + * leaving the area are handled by SDL_EVENT_PEN_DOWN and SDL_EVENT_PEN_UP. + * + * \since This struct is available since SDL 3.1.3. + } + PPSDL_PenProximityEvent = ^PSDL_PenProximityEvent; + PSDL_PenProximityEvent = ^TSDL_PenProximityEvent; + TSDL_PenProximityEvent = record + type_: TSDL_EventType; {*< SDL_EVENT_PEN_PROXIMITY_IN or SDL_EVENT_PEN_PROXIMITY_OUT } + reserved: cuint32; + timestamp: cuint64; {*< In nanoseconds, populated using SDL_GetTicksNS() } + windowID: TSDL_WindowID; {*< The window with mouse focus, if any } + which: TSDL_PenID; {*< The pen instance id } + end; + +{* + * Pressure-sensitive pen motion event structure (event.pmotion.*) + * + * Depending on the hardware, you may get motion events when the pen is not + * touching a tablet, for tracking a pen even when it isn't drawing. You + * should listen for SDL_EVENT_PEN_DOWN and SDL_EVENT_PEN_UP events, or check + * `pen_state & SDL_PEN_INPUT_DOWN` to decide if a pen is "drawing" when + * dealing with pen motion. + * + * \since This struct is available since SDL 3.1.3. + } + PPSDL_PenMotionEvent = ^PSDL_PenMotionEvent; + PSDL_PenMotionEvent = ^TSDL_PenMotionEvent; + TSDL_PenMotionEvent = record + type_: TSDL_EventType; {*< SDL_EVENT_PEN_MOTION } + reserved: cuint32; + timestamp: cuint64; {*< In nanoseconds, populated using SDL_GetTicksNS() } + windowID: TSDL_WindowID; {*< The window with mouse focus, if any } + which: TSDL_PenID; {*< The pen instance id } + pen_state: TSDL_PenInputFlags; {*< Complete pen input state at time of event } + x: cfloat; {*< X coordinate, relative to window } + y: cfloat; {*< Y coordinate, relative to window } + end; + +{* + * Pressure-sensitive pen touched event structure (event.ptouch.*) + * + * These events come when a pen touches a surface (a tablet, etc), or lifts + * off from one. + * + * \since This struct is available since SDL 3.1.3. + } + PPSDL_PenTouchEvent = ^PSDL_PenTouchEvent; + PSDL_PenTouchEvent = ^TSDL_PenTouchEvent; + TSDL_PenTouchEvent = record + type_: TSDL_EventType; {*< SDL_EVENT_PEN_DOWN or SDL_EVENT_PEN_UP } + reserved: cuint32; + timestamp: cuint64; {*< In nanoseconds, populated using SDL_GetTicksNS() } + windowID: TSDL_WindowID; {*< The window with pen focus, if any } + which: TSDL_PenID; {*< The pen instance id } + pen_state: TSDL_PenInputFlags; {*< Complete pen input state at time of event } + x: cfloat; {*< X coordinate, relative to window } + y: cfloat; {*< Y coordinate, relative to window } + eraser: cbool; {*< true if eraser end is used (not all pens support this). } + down: cbool; {*< true if the pen is touching or false if the pen is lifted off } + end; + +{* + * Pressure-sensitive pen button event structure (event.pbutton.*) + * + * This is for buttons on the pen itself that the user might click. The pen + * itself pressing down to draw triggers a SDL_EVENT_PEN_DOWN event instead. + * + * \since This struct is available since SDL 3.1.3. + } + PPSDL_PenButtonEvent = ^PSDL_PenButtonEvent; + PSDL_PenButtonEvent = ^TSDL_PenButtonEvent; + TSDL_PenButtonEvent = record + type_: TSDL_EventType; {*< SDL_EVENT_PEN_BUTTON_DOWN or SDL_EVENT_PEN_BUTTON_UP } + reserved: cuint32; + timestamp: cuint64; {*< In nanoseconds, populated using SDL_GetTicksNS() } + windowID: TSDL_WindowID; {*< The window with mouse focus, if any } + which: TSDL_PenID; {*< The pen instance id } + pen_state: TSDL_PenInputFlags; {*< Complete pen input state at time of event } + x: cfloat; {*< X coordinate, relative to window } + y: cfloat; {*< Y coordinate, relative to window } + button: cuint8; {*< The pen button index (first button is 1). } + down: cbool; {*< true if the button is pressed } + end; + +{* + * Pressure-sensitive pen pressure / angle event structure (event.paxis.*) + * + * You might get some of these events even if the pen isn't touching the + * tablet. + * + * \since This struct is available since SDL 3.1.3. + } + PPSDL_PenAxisEvent = ^PSDL_PenAxisEvent; + PSDL_PenAxisEvent = ^TSDL_PenAxisEvent; + TSDL_PenAxisEvent = record + type_: TSDL_EventType; {*< SDL_EVENT_PEN_AXIS } + reserved: cuint32; + timestamp: cuint64; {*< In nanoseconds, populated using SDL_GetTicksNS() } + windowID: TSDL_WindowID; {*< The window with pen focus, if any } + which: TSDL_PenID; {*< The pen instance id } + pen_state: TSDL_PenInputFlags; {*< Complete pen input state at time of event } + x: cfloat; {*< X coordinate, relative to window } + y: cfloat; {*< Y coordinate, relative to window } + axis: TSDL_PenAxis; {*< Axis that has changed } + value: cfloat; {*< New value of axis } + end; + +{* + * An event used to drop text or request a file open by the system + * (event.drop.*) + * + * \since This struct is available since SDL 3.1.3. + } + PPSDL_DropEvent = ^PSDL_DropEvent; + PSDL_DropEvent = ^TSDL_DropEvent; + TSDL_DropEvent = record + type_: TSDL_EventType; {*< SDL_EVENT_DROP_BEGIN or SDL_EVENT_DROP_FILE or SDL_EVENT_DROP_TEXT or SDL_EVENT_DROP_COMPLETE or SDL_EVENT_DROP_POSITION } + reserved: cuint32; + timestamp: cuint64; {*< In nanoseconds, populated using SDL_GetTicksNS() } + windowID: TSDL_WindowID; {*< The window that was dropped on, if any } + x: cfloat; {*< X coordinate, relative to window (not on begin) } + y: cfloat; {*< Y coordinate, relative to window (not on begin) } + source: PAnsiChar; {*< The source app that sent this drop event, or nil if that isn't available } + data: PAnsiChar; {*< The text for SDL_EVENT_DROP_TEXT and the file name for SDL_EVENT_DROP_FILE, nil for other events } + end; + +{* + * An event triggered when the clipboard contents have changed + * (event.clipboard.*) + * + * \since This struct is available since SDL 3.1.3. + } + PPSDL_ClipboardEvent = ^PSDL_ClipboardEvent; + PSDL_ClipboardEvent = ^TSDL_ClipboardEvent; + TSDL_ClipboardEvent = record + type_: TSDL_EventType; {*< SDL_EVENT_CLIPBOARD_UPDATE } + reserved: cuint32; + timestamp: cuint64; {*< In nanoseconds, populated using SDL_GetTicksNS() } + owner: cbool; {*< are we owning the clipboard (internal update) } + n_mime_types: cint32; {*< number of mime types } + mime_types: ^PAnsiChar; {*< current mime types } + end; + +{* + * Sensor event structure (event.sensor.*) + * + * \since This struct is available since SDL 3.1.3. + } + PPSDL_SensorEvent = ^PSDL_SensorEvent; + PSDL_SensorEvent = ^TSDL_SensorEvent; + TSDL_SensorEvent = record + type_: TSDL_EventType; {*< SDL_EVENT_SENSOR_UPDATE } + reserved: cuint32; + timestamp: cuint64; {*< In nanoseconds, populated using SDL_GetTicksNS() } + which: TSDL_SensorID; {*< The instance ID of the sensor } + data: array[0..5] of cfloat; {*< Up to 6 values from the sensor - additional values can be queried using SDL_GetSensorData() } + sensor_timestamp: cuint64; {*< The timestamp of the sensor reading in nanoseconds, not necessarily synchronized with the system clock } + end; + +{* + * The "quit requested" event + * + * \since This struct is available since SDL 3.1.3. + } + PPSDL_QuitEvent = ^PSDL_QuitEvent; + PSDL_QuitEvent = ^TSDL_QuitEvent; + TSDL_QuitEvent = record + type_: TSDL_EventType; {*< SDL_EVENT_QUIT } + reserved: cuint32; + timestamp: cuint64; {*< In nanoseconds, populated using SDL_GetTicksNS() } + end; + +{* + * A user-defined event type (event.user.*) + * + * This event is unique; it is never created by SDL, but only by the + * application. The event can be pushed onto the event queue using + * SDL_PushEvent(). The contents of the structure members are completely up to + * the programmer; the only requirement is that '''type''' is a value obtained + * from SDL_RegisterEvents(). + * + * \since This struct is available since SDL 3.1.3. + } + PPSDL_UserEvent = ^PSDL_UserEvent; + PSDL_UserEvent = ^TSDL_UserEvent; + TSDL_UserEvent = record + type_: cuint32; {*< SDL_EVENT_USER through SDL_EVENT_LAST-1, Uint32 because these are not in the SDL_EventType enumeration } + reserved: cuint32; + timestamp: cuint64; {*< In nanoseconds, populated using SDL_GetTicksNS() } + windowID: TSDL_WindowID; {*< The associated window if any } + code: cint32; {*< User defined event code } + data1: Pointer; {*< User defined data Pointer } + data2: Pointer; {*< User defined data Pointer } + end; + +{* + * The structure for all events in SDL. + * + * The SDL_Event structure is the core of all event handling in SDL. SDL_Event + * is a union of all event structures used in SDL. + * + * \since This struct is available since SDL 3.1.3. + } +type + PPSDL_Event = ^PSDL_Event; + PSDL_Event = ^TSDL_Event; + TSDL_Event = record + case Integer of + 0: (type_: cuint32); {*< Event type, shared with all events, Uint32 to cover user events which are not in the SDL_EventType enumeration } + 1: (common: TSDL_CommonEvent); {*< Common event data } + 2: (display: TSDL_DisplayEvent); {*< Display event data } + 3: (window: TSDL_WindowEvent); {*< Window event data } + 4: (kdevice: TSDL_KeyboardDeviceEvent); {*< Keyboard device change event data } + 5: (key: TSDL_KeyboardEvent); {*< Keyboard event data } + 6: (edit: TSDL_TextEditingEvent); {*< Text editing event data } + 7: (edit_candidates: TSDL_TextEditingCandidatesEvent); {*< Text editing candidates event data } + 8: (text: TSDL_TextInputEvent); {*< Text input event data } + 9: (mdevice: TSDL_MouseDeviceEvent); {*< Mouse device change event data } + 10: (motion: TSDL_MouseMotionEvent); {*< Mouse motion event data } + 11: (button: TSDL_MouseButtonEvent); {*< Mouse button event data } + 12: (wheel: TSDL_MouseWheelEvent); {*< Mouse wheel event data } + 13: (jdevice: TSDL_JoyDeviceEvent); {*< Joystick device change event data } + 14: (jaxis: TSDL_JoyAxisEvent); {*< Joystick axis event data } + 15: (jball: TSDL_JoyBallEvent); {*< Joystick ball event data } + 16: (jhat: TSDL_JoyHatEvent); {*< Joystick hat event data } + 17: (jbutton: TSDL_JoyButtonEvent); {*< Joystick button event data } + 18: (jbattery: TSDL_JoyBatteryEvent); {*< Joystick battery event data } + 19: (gdevice: TSDL_GamepadDeviceEvent); {*< Gamepad device event data } + 20: (gaxis: TSDL_GamepadAxisEvent); {*< Gamepad axis event data } + 21: (gbutton: TSDL_GamepadButtonEvent); {*< Gamepad button event data } + 22: (gtouchpad: TSDL_GamepadTouchpadEvent); {*< Gamepad touchpad event data } + 23: (gsensor: TSDL_GamepadSensorEvent); {*< Gamepad sensor event data } + 24: (adevice: TSDL_AudioDeviceEvent); {*< Audio device event data } + 25: (cdevice: TSDL_CameraDeviceEvent); {*< Camera device event data } + 26: (sensor: TSDL_SensorEvent); {*< Sensor event data } + 27: (quit: TSDL_QuitEvent); {*< Quit request event data } + 28: (user: TSDL_UserEvent); {*< Custom event data } + 29: (tfinger: TSDL_TouchFingerEvent); {*< Touch finger event data } + 30: (pproximity: TSDL_PenProximityEvent); {*< Pen proximity event data } + 31: (ptouch: TSDL_PenTouchEvent); {*< Pen tip touching event data } + 32: (pmotion: TSDL_PenMotionEvent); {*< Pen motion event data } + 33: (pbutton: TSDL_PenButtonEvent); {*< Pen button event data } + 34: (paxis: TSDL_PenAxisEvent); {*< Pen axis event data } + 35: (drop: TSDL_DropEvent); {*< Drag and drop event data } + 36: (clipboard: TSDL_ClipboardEvent); {*< Clipboard event data } + + { This is necessary for ABI compatibility between Visual C++ and GCC. + Visual C++ will respect the push pack pragma and use 52 bytes (size of + SDL_TextEditingEvent, the largest structure for 32-bit and 64-bit + architectures) for this union, and GCC will use the alignment of the + largest datatype within the union, which is 8 bytes on 64-bit + architectures. + + So... we'll add padding to force the size to be the same for both. + + On architectures where pointers are 16 bytes, this needs rounding up to + 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. + } + 37: (padding: array[0..127] of cuint8); + end; + +{ #todo : SDL3-for-Pascal: Translation of SDL_COMPILE_TIME_ASSERT necessary? Looks like an internal test function. } +{ Make sure we haven't broken binary compatibility } +{ C code: SDL_COMPILE_TIME_ASSERT(SDL_Event, sizeof(SDL_Event) == sizeof(((SDL_Event *)NULL)->padding)); } + +{ Function prototypes } + +{* + * Pump the event loop, gathering events from the input devices. + * + * This function updates the event queue and internal input device state. + * + * SDL_PumpEvents() gathers all the pending input information from devices and + * places it in the event queue. Without calls to SDL_PumpEvents() no events + * would ever be placed on the queue. Often the need for calls to + * SDL_PumpEvents() is hidden from the user since SDL_PollEvent() and + * SDL_WaitEvent() implicitly call SDL_PumpEvents(). However, if you are not + * polling or waiting for events (e.g. you are filtering them), then you must + * call SDL_PumpEvents() to force an event queue update. + * + * \threadsafety This should only be run in the thread that initialized the + * video subsystem, and for extra safety, you should consider + * only doing those things on the main thread in any case. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_PollEvent + * \sa SDL_WaitEvent + } +procedure SDL_PumpEvents; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_PumpEvents' {$ENDIF} {$ENDIF}; + +{* + * The type of action to request from SDL_PeepEvents(). + * + * \since This enum is available since SDL 3.1.3. + } +type + PPSDL_EventAction = ^PSDL_EventAction; + PSDL_EventAction = ^TSDL_EventAction; + TSDL_EventAction = type Integer; + const + SDL_ADDEVENT = TSDL_EventAction(0); {*< Add events to the back of the queue. } + SDL_PEEKEVENT = TSDL_EventAction(1); {*< Check but don't remove events from the queue front. } + SDL_GETEVENT = TSDL_EventAction(2); {*< Retrieve/remove events from the front of the queue. } + +{* + * Check the event queue for messages and optionally return them. + * + * `action` may be any of the following: + * + * - `SDL_ADDEVENT`: up to `numevents` events will be added to the back of the + * event queue. + * - `SDL_PEEKEVENT`: `numevents` events at the front of the event queue, + * within the specified minimum and maximum type, will be returned to the + * caller and will _not_ be removed from the queue. If you pass nil for + * `events`, then `numevents` is ignored and the total number of matching + * events will be returned. + * - `SDL_GETEVENT`: up to `numevents` events at the front of the event queue, + * within the specified minimum and maximum type, will be returned to the + * caller and will be removed from the queue. + * + * You may have to call SDL_PumpEvents() before calling this function. + * Otherwise, the events may not be ready to be filtered when you call + * SDL_PeepEvents(). + * + * \param events destination buffer for the retrieved events, may be nil to + * leave the events in the queue and return the number of events + * that would have been stored. + * \param numevents if action is SDL_ADDEVENT, the number of events to add + * back to the event queue; if action is SDL_PEEKEVENT or + * SDL_GETEVENT, the maximum number of events to retrieve. + * \param action action to take; see [[#action|Remarks]] for details. + * \param minType minimum value of the event type to be considered; + * SDL_EVENT_FIRST is a safe choice. + * \param maxType maximum value of the event type to be considered; + * SDL_EVENT_LAST is a safe choice. + * \returns the number of events actually stored or -1 on failure; call + * SDL_GetError() for more information. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_PollEvent + * \sa SDL_PumpEvents + * \sa SDL_PushEvent + } +function SDL_PeepEvents(events: PSDL_Event; numevents: cint; action: TSDL_EventAction; minType: cuint32; maxType: cuint32): cint; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_PeepEvents' {$ENDIF} {$ENDIF}; + +{* + * Check for the existence of a certain event type in the event queue. + * + * If you need to check for a range of event types, use SDL_HasEvents() + * instead. + * + * \param type the type of event to be queried; see SDL_EventType for details. + * \returns true if events matching `type` are present, or false if events + * matching `type` are not present. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_HasEvents + } +function SDL_HasEvent(type_: cuint32): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HasEvent' {$ENDIF} {$ENDIF}; + +{* + * Check for the existence of certain event types in the event queue. + * + * If you need to check for a single event type, use SDL_HasEvent() instead. + * + * \param minType the low end of event type to be queried, inclusive; see + * SDL_EventType for details. + * \param maxType the high end of event type to be queried, inclusive; see + * SDL_EventType for details. + * \returns true if events with type >= `minType` and <= `maxType` are + * present, or false if not. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_HasEvents + } +function SDL_HasEvents(minType: cuint32; maxType: cuint32): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HasEvents' {$ENDIF} {$ENDIF}; + +{* + * Clear events of a specific type from the event queue. + * + * This will unconditionally remove any events from the queue that match + * `type`. If you need to remove a range of event types, use SDL_FlushEvents() + * instead. + * + * It's also normal to just ignore events you don't care about in your event + * loop without calling this function. + * + * This function only affects currently queued events. If you want to make + * sure that all pending OS events are flushed, you can call SDL_PumpEvents() + * on the main thread immediately before the flush call. + * + * If you have user events with custom data that needs to be freed, you should + * use SDL_PeepEvents() to remove and clean up those events before calling + * this function. + * + * \param type the type of event to be cleared; see SDL_EventType for details. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_FlushEvents + } +procedure SDL_FlushEvent(type_: cuint32); cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_FlushEvent' {$ENDIF} {$ENDIF}; + +{* + * Clear events of a range of types from the event queue. + * + * This will unconditionally remove any events from the queue that are in the + * range of `minType` to `maxType`, inclusive. If you need to remove a single + * event type, use SDL_FlushEvent() instead. + * + * It's also normal to just ignore events you don't care about in your event + * loop without calling this function. + * + * This function only affects currently queued events. If you want to make + * sure that all pending OS events are flushed, you can call SDL_PumpEvents() + * on the main thread immediately before the flush call. + * + * \param minType the low end of event type to be cleared, inclusive; see + * SDL_EventType for details. + * \param maxType the high end of event type to be cleared, inclusive; see + * SDL_EventType for details. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_FlushEvent + } +procedure SDL_FlushEvents(minType: cuint32; maxType: cuint32); cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_FlushEvents' {$ENDIF} {$ENDIF}; + +{* + * Poll for currently pending events. + * + * If `event` is not nil, the next event is removed from the queue and stored + * in the SDL_Event structure pointed to by `event`. The 1 returned refers to + * this event, immediately stored in the SDL Event structure -- not an event + * to follow. + * + * If `event` is nil, it simply returns 1 if there is an event in the queue, + * but will not remove it from the queue. + * + * As this function may implicitly call SDL_PumpEvents(), you can only call + * this function in the thread that set the video mode. + * + * SDL_PollEvent() is the favored way of receiving system events since it can + * be done from the main loop and does not suspend the main loop while waiting + * on an event to be posted. + * + * The common practice is to fully process the event queue once every frame, + * usually as a first step before updating the game's state: + * + * ```c + * while (game_is_still_running) + * SDL_Event event; + * while (SDL_PollEvent(&event)) // poll until all events are handled! + * // decide what to do with this event. + * + * + * // update game state, draw the current frame + * + * ``` + * + * \param event the SDL_Event structure to be filled with the next event from + * the queue, or nil. + * \returns true if this got an event or false if there are none available. + * + * \threadsafety This should only be run in the thread that initialized the + * video subsystem, and for extra safety, you should consider + * only doing those things on the main thread in any case. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_PushEvent + * \sa SDL_WaitEvent + * \sa SDL_WaitEventTimeout + } +function SDL_PollEvent(event: PSDL_Event): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_PollEvent' {$ENDIF} {$ENDIF}; + +{* + * Wait indefinitely for the next available event. + * + * If `event` is not nil, 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. + * + * \param event the SDL_Event structure to be filled in with the next event + * from the queue, or nil. + * \returns true on success or false if there was an error while waiting for + * events; call SDL_GetError() for more information. + * + * \threadsafety This should only be run in the thread that initialized the + * video subsystem, and for extra safety, you should consider + * only doing those things on the main thread in any case. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_PollEvent + * \sa SDL_PushEvent + * \sa SDL_WaitEventTimeout + } +function SDL_WaitEvent(event: PSDL_Event): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_WaitEvent' {$ENDIF} {$ENDIF}; + +{* + * Wait until the specified timeout (in milliseconds) for the next available + * event. + * + * If `event` is not nil, 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 nil. + * \param timeoutMS the maximum number of milliseconds to wait for the next + * available event. + * \returns true if this got an event or false if the timeout elapsed without + * any events available. + * + * \threadsafety This should only be run in the thread that initialized the + * video subsystem, and for extra safety, you should consider + * only doing those things on the main thread in any case. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_PollEvent + * \sa SDL_PushEvent + * \sa SDL_WaitEvent + } +function SDL_WaitEventTimeout(event: PSDL_Event; timeoutMS: cint32): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_WaitEventTimeout' {$ENDIF} {$ENDIF}; + +{* + * Add an event to the event queue. + * + * The event queue can actually be used as a two way communication channel. + * Not only can events be read from the queue, but the user can also push + * their own events onto it. `event` is a Pointer to the event structure you + * wish to push onto the queue. The event is copied into the queue, and the + * caller may dispose of the memory pointed to after SDL_PushEvent() returns. + * + * Note: Pushing device input events onto the queue doesn't modify the state + * of the device within SDL. + * + * Note: Events pushed onto the queue with SDL_PushEvent() get passed through + * the event filter but events added with SDL_PeepEvents() do not. + * + * For pushing application-specific events, please use SDL_RegisterEvents() to + * get an event type that does not conflict with other code that also wants + * its own custom event types. + * + * \param event the SDL_Event to be added to the queue. + * \returns true on success, false if the event was filtered or on failure; + * call SDL_GetError() for more information. A common reason for + * error is the event queue being full. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_PeepEvents + * \sa SDL_PollEvent + * \sa SDL_RegisterEvents + } +function SDL_PushEvent(event: PSDL_Event): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_PushEvent' {$ENDIF} {$ENDIF}; + +{* + * A function Pointer used for callbacks that watch the event queue. + * + * \param userdata what was passed as `userdata` to SDL_SetEventFilter() or + * SDL_AddEventWatch, etc. + * \param event the event that triggered the callback. + * \returns true to permit event to be added to the queue, and false to + * disallow it. When used with SDL_AddEventWatch, the return value is + * ignored. + * + * \threadsafety SDL may call this callback at any time from any thread; the + * application is responsible for locking resources the callback + * touches that need to be protected. + * + * \since This datatype is available since SDL 3.1.3. + * + * \sa SDL_SetEventFilter + * \sa SDL_AddEventWatch + } +type + PSDL_EventFilter = ^TSDL_EventFilter; + TSDL_EventFilter = function (userdata: Pointer; event: PSDL_Event): cbool; cdecl; + +{* + * Set up a filter to process all events before they change internal state and + * are posted to the internal event queue. + * + * If the filter function returns true when called, then the event will be + * added to the internal queue. If it returns false, then the event will be + * dropped from the queue, but the internal state will still be updated. This + * allows selective filtering of dynamically arriving events. + * + * **WARNING**: Be very careful of what you do in the event filter function, + * as it may run in a different thread! + * + * On platforms that support it, if the quit event is generated by an + * interrupt signal (e.g. pressing Ctrl-C), it will be delivered to the + * application at the next event poll. + * + * There is one caveat when dealing with the SDL_QuitEvent event type. The + * event filter is only called when the window manager desires to close the + * application window. If the event filter returns 1, then the window will be + * closed, otherwise the window will remain open if possible. + * + * Note: Disabled events never make it to the event filter function; see + * SDL_SetEventEnabled(). + * + * Note: If you just want to inspect events without filtering, you should use + * SDL_AddEventWatch() instead. + * + * Note: Events pushed onto the queue with SDL_PushEvent() get passed through + * the event filter, but events pushed onto the queue with SDL_PeepEvents() do + * not. + * + * \param filter an SDL_EventFilter function to call when an event happens. + * \param userdata a Pointer that is passed to `filter`. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_AddEventWatch + * \sa SDL_SetEventEnabled + * \sa SDL_GetEventFilter + * \sa SDL_PeepEvents + * \sa SDL_PushEvent + } +procedure SDL_SetEventFilter(filter: TSDL_EventFilter; userdata: Pointer); cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetEventFilter' {$ENDIF} {$ENDIF}; + +{* + * Query the current event filter. + * + * This function can be used to "chain" filters, by saving the existing filter + * before replacing it with a function that will call that saved filter. + * + * \param filter the current callback function will be stored here. + * \param userdata the Pointer that is passed to the current event filter will + * be stored here. + * \returns true on success or false if there is no event filter set. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_SetEventFilter + } +function SDL_GetEventFilter(filter: PSDL_EventFilter; userdata: PPointer): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetEventFilter' {$ENDIF} {$ENDIF}; + +{* + * Add a callback to be triggered when an event is added to the event queue. + * + * `filter` will be called when an event happens, and its return value is + * ignored. + * + * **WARNING**: Be very careful of what you do in the event filter function, + * as it may run in a different thread! + * + * If the quit event is generated by a signal (e.g. SIGINT), it will bypass + * the internal queue and be delivered to the watch callback immediately, and + * arrive at the next event poll. + * + * Note: the callback is called for events posted by the user through + * SDL_PushEvent(), but not for disabled events, nor for events by a filter + * callback set with SDL_SetEventFilter(), nor for events posted by the user + * through SDL_PeepEvents(). + * + * \param filter an SDL_EventFilter function to call when an event happens. + * \param userdata a Pointer that is passed to `filter`. + * \returns true on success or false on failure; call SDL_GetError() for more + * information. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_RemoveEventWatch + * \sa SDL_SetEventFilter + } +function SDL_AddEventWatch(filter: TSDL_EventFilter; userdata: Pointer): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_AddEventWatch' {$ENDIF} {$ENDIF}; + +{* + * Remove an event watch callback added with SDL_AddEventWatch(). + * + * This function takes the same input as SDL_AddEventWatch() to identify and + * delete the corresponding callback. + * + * \param filter the function originally passed to SDL_AddEventWatch(). + * \param userdata the Pointer originally passed to SDL_AddEventWatch(). + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_AddEventWatch + } +procedure SDL_RemoveEventWatch(filter: TSDL_EventFilter; userdata: Pointer); cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RemoveEventWatch' {$ENDIF} {$ENDIF}; + +{* + * Run a specific filter function on the current event queue, removing any + * events for which the filter returns false. + * + * See SDL_SetEventFilter() for more information. Unlike SDL_SetEventFilter(), + * this function does not change the filter permanently, it only uses the + * supplied filter until this function returns. + * + * \param filter the SDL_EventFilter function to call when an event happens. + * \param userdata a Pointer that is passed to `filter`. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetEventFilter + * \sa SDL_SetEventFilter + } +procedure SDL_FilterEvents(filter: TSDL_EventFilter; userdata: Pointer); cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_FilterEvents' {$ENDIF} {$ENDIF}; + +{* + * Set the state of processing events by type. + * + * \param type the type of event; see SDL_EventType for details. + * \param enabled whether to process the event or not. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_EventEnabled + } +procedure SDL_SetEventEnabled(type_: cuint32; enabled: cbool); cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetEventEnabled' {$ENDIF} {$ENDIF}; + +{* + * Query the state of processing events by type. + * + * \param type the type of event; see SDL_EventType for details. + * \returns true if the event is being processed, false otherwise. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_SetEventEnabled + } +function SDL_EventEnabled(type_: cuint32): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_EventEnabled' {$ENDIF} {$ENDIF}; + +{* + * Allocate a set of user-defined events, and return the beginning event + * number for that set of events. + * + * \param numevents the number of events to be allocated. + * \returns the beginning event number, or 0 if numevents is invalid or if + * there are not enough user-defined events left. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_PushEvent + } +function SDL_RegisterEvents(numevents: cint): cuint32; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RegisterEvents' {$ENDIF} {$ENDIF}; + +{* + * Get window associated with an event. + * + * \param event an event containing a `windowID`. + * \returns the associated window on success or nil if there is none. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_PollEvent + * \sa SDL_WaitEvent + * \sa SDL_WaitEventTimeout + } +function SDL_GetWindowFromEvent(event: PSDL_Event): PSDL_Window; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetWindowFromEvent' {$ENDIF} {$ENDIF}; diff --git a/units/SDL_guid.inc b/units/SDL_guid.inc new file mode 100644 index 0000000..14e539f --- /dev/null +++ b/units/SDL_guid.inc @@ -0,0 +1,72 @@ +{ + This file is part of: + + SDL3 for Pascal + (https://github.com/PascalGameDevelopment/SDL3-for-Pascal) + SPDX-License-Identifier: Zlib +} + +{* + * # CategoryGUID + * + * A GUID is a 128-bit value that represents something that is uniquely + * identifiable by this value: "globally unique." + } + +{* + * An SDL_GUID is a 128-bit identifier for an input device that identifies + * that device across runs of SDL programs on the same platform. + * + * If the device is detached and then re-attached to a different port, or if + * the base system is rebooted, the device should still report the same GUID. + * + * GUIDs are as precise as possible but are not guaranteed to distinguish + * physically distinct but equivalent devices. For example, two game + * controllers from the same vendor with the same product ID and revision may + * have the same GUID. + * + * GUIDs may be platform-dependent (i.e., the same device may report different + * GUIDs on different operating systems). + * + * \since This struct is available since SDL 3.1.3. + } +type + PPSDL_GUID = ^PSDL_GUID; + PSDL_GUID = ^TSDL_GUID; + TSDL_GUID = record + data: array[0..15] of cuint8; + end; + +{ Function prototypes } + +{* + * Get an ASCII string representation for a given SDL_GUID. + * + * \param guid the SDL_GUID you wish to convert to string. + * \param pszGUID buffer in which to write the ASCII string. + * \param cbGUID the size of pszGUID, should be at least 33 bytes. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_StringToGUID + } +procedure SDL_GUIDToString(guid: TSDL_GUID; pszGUID: PAnsiChar; cbGUID: cint); cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GUIDToString' {$ENDIF} {$ENDIF}; + +{* + * Convert a GUID string into a SDL_GUID structure. + * + * Performs no error checking. If this function is given a string containing + * an invalid GUID, the function will silently succeed, but the GUID generated + * will not be useful. + * + * \param pchGUID string containing an ASCII representation of a GUID. + * \returns a SDL_GUID structure. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GUIDToString + } +function SDL_StringToGUID(pchGUID: PAnsiChar): TSDL_GUID; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_StringToGUID' {$ENDIF} {$ENDIF}; + diff --git a/units/SDL_joystick.inc b/units/SDL_joystick.inc new file mode 100644 index 0000000..ef3a0c0 --- /dev/null +++ b/units/SDL_joystick.inc @@ -0,0 +1,1229 @@ +{ + This file is part of: + + SDL3 for Pascal + (https://github.com/PascalGameDevelopment/SDL3-for-Pascal) + SPDX-License-Identifier: Zlib +} + +{* + * # CategoryJoystick + * + * SDL joystick support. + * + * This is the lower-level joystick handling. If you want the simpler option, + * where what buttons does what is well-defined, you should use the gamepad + * API instead. + * + * The term "instance_id" is the current instantiation of a joystick device in + * the system, if the joystick is removed and then re-inserted then it will + * get a new instance_id, instance_id's are monotonically increasing + * identifiers of a joystick plugged in. + * + * The term "player_index" is the number assigned to a player on a specific + * controller. For XInput controllers this returns the XInput user index. Many + * joysticks will not be able to supply this information. + * + * SDL_GUID is used as a stable 128-bit identifier for a joystick device that + * does not change over time. It identifies class of the device (a X360 wired + * controller for example). This identifier is platform dependent. + * + * In order to use these functions, SDL_Init() must have been called with the + * SDL_INIT_JOYSTICK flag. This causes SDL to scan the system for joysticks, + * and load appropriate drivers. + * + * If you would like to receive joystick updates while the application is in + * the background, you should set the following hint before calling + * SDL_Init(): SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS + } + +{* + * The joystick structure used to identify an SDL joystick. + * + * This is opaque data. + * + * \since This struct is available since SDL 3.1.3. + } +type + PPSDL_Joystick = ^PSDL_Joystick; + PSDL_Joystick = type Pointer; + +{* + * This is a unique ID for a joystick for the time it is connected to the + * system, and is never reused for the lifetime of the application. + * + * If the joystick is disconnected and reconnected, it will get a new ID. + * + * The value 0 is an invalid ID. + * + * \since This datatype is available since SDL 3.1.3. + } +type + PPSDL_JoystickID = ^PSDL_JoystickID; + PSDL_JoystickID = ^TSDL_JoystickID; + TSDL_JoystickID = cuint32; + +{* + * An enum of some common joystick types. + * + * In some cases, SDL can identify a low-level joystick as being a certain + * type of device, and will report it through SDL_GetJoystickType (or + * SDL_GetJoystickTypeForID). + * + * This is by no means a complete list of everything that can be plugged into + * a computer. + * + * \since This enum is available since SDL 3.1.3. + } +type + PPSDL_JoystickType = ^PSDL_JoystickType; + PSDL_JoystickType = ^TSDL_JoystickType; + TSDL_JoystickType = Integer; +const + SDL_JOYSTICK_TYPE_UNKNOWN = TSDL_JoystickType(0); + SDL_JOYSTICK_TYPE_GAMEPAD = TSDL_JoystickType(1); + SDL_JOYSTICK_TYPE_WHEEL = TSDL_JoystickType(2); + SDL_JOYSTICK_TYPE_ARCADE_STICK = TSDL_JoystickType(3); + SDL_JOYSTICK_TYPE_FLIGHT_STICK = TSDL_JoystickType(4); + SDL_JOYSTICK_TYPE_DANCE_PAD = TSDL_JoystickType(5); + SDL_JOYSTICK_TYPE_GUITAR = TSDL_JoystickType(6); + SDL_JOYSTICK_TYPE_DRUM_KIT = TSDL_JoystickType(7); + SDL_JOYSTICK_TYPE_ARCADE_PAD = TSDL_JoystickType(8); + SDL_JOYSTICK_TYPE_THROTTLE = TSDL_JoystickType(9); + SDL_JOYSTICK_TYPE_COUNT = TSDL_JoystickType(10); + +{* + * Possible connection states for a joystick device. + * + * This is used by SDL_GetJoystickConnectionState to report how a device is + * connected to the system. + * + * \since This enum is available since SDL 3.1.3. + } +type + PPSDL_JoystickConnectionState = ^PSDL_JoystickConnectionState; + PSDL_JoystickConnectionState = ^TSDL_JoystickConnectionState; + TSDL_JoystickConnectionState = Integer; +const + SDL_JOYSTICK_CONNECTION_INVALID = TSDL_JoystickConnectionState(-1); + SDL_JOYSTICK_CONNECTION_UNKNOWN = TSDL_JoystickConnectionState(0); + SDL_JOYSTICK_CONNECTION_WIRED = TSDL_JoystickConnectionState(1); + SDL_JOYSTICK_CONNECTION_WIRELESS = TSDL_JoystickConnectionState(2); + +{* + * The largest value an SDL_Joystick's axis can report. + * + * \since This macro is available since SDL 3.1.3. + * + * \sa SDL_JOYSTICK_AXIS_MIN + } + SDL_JOYSTICK_AXIS_MAX = 32767; + +{* + * The smallest value an SDL_Joystick's axis can report. + * + * This is a negative number! + * + * \since This macro is available since SDL 3.1.3. + * + * \sa SDL_JOYSTICK_AXIS_MAX + } + SDL_JOYSTICK_AXIS_MIN = -32768; + +{ Function prototypes } + +{* + * Locking for atomic access to the joystick API. + * + * The SDL joystick functions are thread-safe, however you can lock the + * joysticks while processing to guarantee that the joystick list won't change + * and joystick and gamepad events will not be delivered. + * + * \since This function is available since SDL 3.1.3. + } +{ #todo : SDL3-for-Pascal: Translate } +{void SDL_LockJoysticks(void) SDL_ACQUIRE(SDL_joystick_lock);} + +{* + * Unlocking for atomic access to the joystick API. + * + * \since This function is available since SDL 3.1.3. + } + { #todo : SDL3-for-Pascal: Translate} +{void SDL_UnlockJoysticks(void) SDL_RELEASE(SDL_joystick_lock);} + +{* + * Return whether a joystick is currently connected. + * + * \returns true if a joystick is connected, false otherwise. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetJoysticks + } +function SDL_HasJoystick: cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HasJoystick' {$ENDIF} {$ENDIF}; + +{* + * Get a list of currently connected joysticks. + * + * \param count a Pointer filled in with the number of joysticks returned, may + * be nil. + * \returns a 0 terminated array of joystick instance IDs or nil on failure; + * call SDL_GetError() for more information. This should be freed + * with SDL_free() when it is no longer needed. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_HasJoystick + * \sa SDL_OpenJoystick + } +function SDL_GetJoysticks(count: pcint): PSDL_JoystickID; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetJoysticks' {$ENDIF} {$ENDIF}; + +{* + * Get the implementation dependent name of a joystick. + * + * This can be called before any joysticks are opened. + * + * \param instance_id the joystick instance ID. + * \returns the name of the selected joystick. If no name can be found, this + * function returns nil; call SDL_GetError() for more information. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetJoystickName + * \sa SDL_GetJoysticks + } +function SDL_GetJoystickNameForID(instance_id: TSDL_JoystickID): PAnsiChar; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetJoystickNameForID' {$ENDIF} {$ENDIF}; + +{* + * Get the implementation dependent path of a joystick. + * + * This can be called before any joysticks are opened. + * + * \param instance_id the joystick instance ID. + * \returns the path of the selected joystick. If no path can be found, this + * function returns nil; call SDL_GetError() for more information. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetJoystickPath + * \sa SDL_GetJoysticks + } +function SDL_GetJoystickPathForID(instance_id: TSDL_JoystickID): PAnsiChar; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetJoystickPathForID' {$ENDIF} {$ENDIF}; + +{* + * Get the player index of a joystick. + * + * This can be called before any joysticks are opened. + * + * \param instance_id the joystick instance ID. + * \returns the player index of a joystick, or -1 if it's not available. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetJoystickPlayerIndex + * \sa SDL_GetJoysticks + } +function SDL_GetJoystickPlayerIndexForID(instance_id: TSDL_JoystickID): cint; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetJoystickPlayerIndexForID' {$ENDIF} {$ENDIF}; + +{* + * Get the implementation-dependent GUID of a joystick. + * + * This can be called before any joysticks are opened. + * + * \param instance_id the joystick instance ID. + * \returns the GUID of the selected joystick. If called with an invalid + * instance_id, this function returns a zero GUID. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetJoystickGUID + * \sa SDL_GUIDToString + } +function SDL_GetJoystickGUIDForID(instance_id: TSDL_JoystickID): TSDL_GUID; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetJoystickGUIDForID' {$ENDIF} {$ENDIF}; + +{* + * Get the USB vendor ID of a joystick, if available. + * + * This can be called before any joysticks are opened. If the vendor ID isn't + * available this function returns 0. + * + * \param instance_id the joystick instance ID. + * \returns the USB vendor ID of the selected joystick. If called with an + * invalid instance_id, this function returns 0. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetJoystickVendor + * \sa SDL_GetJoysticks + } +function SDL_GetJoystickVendorForID(instance_id: TSDL_JoystickID): cuint16; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetJoystickVendorForID' {$ENDIF} {$ENDIF}; + +{* + * Get the USB product ID of a joystick, if available. + * + * This can be called before any joysticks are opened. If the product ID isn't + * available this function returns 0. + * + * \param instance_id the joystick instance ID. + * \returns the USB product ID of the selected joystick. If called with an + * invalid instance_id, this function returns 0. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetJoystickProduct + * \sa SDL_GetJoysticks + } +function SDL_GetJoystickProductForID(instance_id: TSDL_JoystickID): cuint16; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetJoystickProductForID' {$ENDIF} {$ENDIF}; + +{* + * Get the product version of a joystick, if available. + * + * This can be called before any joysticks are opened. If the product version + * isn't available this function returns 0. + * + * \param instance_id the joystick instance ID. + * \returns the product version of the selected joystick. If called with an + * invalid instance_id, this function returns 0. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetJoystickProductVersion + * \sa SDL_GetJoysticks + } +function SDL_GetJoystickProductVersionForID(instance_id: TSDL_JoystickID): cuint16; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetJoystickProductVersionForID' {$ENDIF} {$ENDIF}; + +{* + * Get the type of a joystick, if available. + * + * This can be called before any joysticks are opened. + * + * \param instance_id the joystick instance ID. + * \returns the SDL_JoystickType of the selected joystick. If called with an + * invalid instance_id, this function returns + * `SDL_JOYSTICK_TYPE_UNKNOWN`. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetJoystickType + * \sa SDL_GetJoysticks + } +function SDL_GetJoystickTypeForID(instance_id: TSDL_JoystickID): TSDL_JoystickType; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetJoystickTypeForID' {$ENDIF} {$ENDIF}; + +{* + * Open a joystick for use. + * + * The joystick subsystem must be initialized before a joystick can be opened + * for use. + * + * \param instance_id the joystick instance ID. + * \returns a joystick identifier or nil on failure; call SDL_GetError() for + * more information. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_CloseJoystick + } +function SDL_OpenJoystick(instance_id: TSDL_JoystickID): PSDL_Joystick; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_OpenJoystick' {$ENDIF} {$ENDIF}; + +{* + * Get the SDL_Joystick associated with an instance ID, if it has been opened. + * + * \param instance_id the instance ID to get the SDL_Joystick for. + * \returns an SDL_Joystick on success or nil on failure or if it hasn't been + * opened yet; call SDL_GetError() for more information. + * + * \since This function is available since SDL 3.1.3. + } +function SDL_GetJoystickFromID(instance_id: TSDL_JoystickID): PSDL_Joystick; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetJoystickFromID' {$ENDIF} {$ENDIF}; + +{* + * Get the SDL_Joystick associated with a player index. + * + * \param player_index the player index to get the SDL_Joystick for. + * \returns an SDL_Joystick on success or nil on failure; call SDL_GetError() + * for more information. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetJoystickPlayerIndex + * \sa SDL_SetJoystickPlayerIndex + } +function SDL_GetJoystickFromPlayerIndex(player_index: cint): PSDL_Joystick; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetJoystickFromPlayerIndex' {$ENDIF} {$ENDIF}; + +{* + * The structure that describes a virtual joystick touchpad. + * + * \since This struct is available since SDL 3.1.3. + * + * \sa SDL_VirtualJoystickDesc + } +type + PPSDL_VirtualJoystickTouchpadDesc = ^PSDL_VirtualJoystickTouchpadDesc; + PSDL_VirtualJoystickTouchpadDesc = ^TSDL_VirtualJoystickTouchpadDesc; + TSDL_VirtualJoystickTouchpadDesc = record + nfingers: cuint16; {*< the number of simultaneous fingers on this touchpad } + padding: array[0..2] of cuint16; + end; + +{* + * The structure that describes a virtual joystick sensor. + * + * \since This struct is available since SDL 3.1.3. + * + * \sa SDL_VirtualJoystickDesc + } + PPSDL_VirtualJoystickSensorDesc = ^PSDL_VirtualJoystickSensorDesc; + PSDL_VirtualJoystickSensorDesc = ^TSDL_VirtualJoystickSensorDesc; + TSDL_VirtualJoystickSensorDesc = record + type_: TSDL_SensorType; {*< the type of this sensor } + rate: cfloat; {*< the update frequency of this sensor, may be 0.0f } + end; + +{* + * The structure that describes a virtual joystick. + * + * This structure should be initialized using SDL_INIT_INTERFACE(). All + * elements of this structure are optional. + * + * \since This struct is available since SDL 3.1.3. + * + * \sa SDL_AttachVirtualJoystick + * \sa SDL_INIT_INTERFACE + * \sa SDL_VirtualJoystickSensorDesc + * \sa SDL_VirtualJoystickTouchpadDesc + } +type + PPSDL_VirtualJoystickDesc = ^PSDL_VirtualJoystickDesc; + PSDL_VirtualJoystickDesc = ^TSDL_VirtualJoystickDesc; + TSDL_VirtualJoystickDesc = record + version: cuint32; {*< the version of this interface } + type_: cuint16; {*< `SDL_JoystickType` } + padding: cuint16; {*< unused } + vendor_id: cuint16; {*< the USB vendor ID of this joystick } + product_id: cuint16; {*< the USB product ID of this joystick } + naxes: cuint16; {*< the number of axes on this joystick } + nbuttons: cuint16; {*< the number of buttons on this joystick } + nballs: cuint16; {*< the number of balls on this joystick } + nhats: cuint16; {*< the number of hats on this joystick } + ntouchpads: cuint16; {*< the number of touchpads on this joystick, requires `touchpads` to point at valid descriptions } + nsensors: cuint16; {*< the number of sensors on this joystick, requires `sensors` to point at valid descriptions } + padding2: array[0..1] of cuint16; {*< unused } + button_mask: cuint32; {*< A mask of which buttons are valid for this controller + e.g. (1 << SDL_GAMEPAD_BUTTON_SOUTH) } + axis_mask: cuint32; {*< A mask of which axes are valid for this controller + e.g. (1 << SDL_GAMEPAD_AXIS_LEFTX) } + name: PAnsiChar; {*< the name of the joystick } + touchpads: PSDL_VirtualJoystickTouchpadDesc; {*< A Pointer to an array of touchpad descriptions, required if `ntouchpads` is > 0 } + sensors: PSDL_VirtualJoystickSensorDesc; {*< A Pointer to an array of sensor descriptions, required if `nsensors` is > 0 } + { #todo : SDL3-for-Pascal: Should the following function defs. be cdecl or not? } + userdata: Pointer; {*< User data Pointer passed to callbacks } + Update: procedure (userdata: Pointer); cdecl; {*< Called when the joystick state should be updated } + SetPlayerIndex: procedure (userdata: Pointer; player_index: cint); cdecl; {*< Called when the player index is set } + Rumble: function (userdata: Pointer; low_frequency_rumble: cuint16; high_frequency_rumble: cuint16): cbool; cdecl; {*< Implements SDL_RumbleJoystick() } + RumbleTriggers: function (userdata: Pointer; left_rumble: cuint16; right_rumble: cuint16): cbool; cdecl; {*< Implements SDL_RumbleJoystickTriggers() } + SetLED: function (userdata: Pointer; red: cuint8; green: cuint8; blue: cuint8): cbool; cdecl; {*< Implements SDL_SetJoystickLED() } + SendEffect: function (userdata: Pointer; data: Pointer; size: cint): cbool; cdecl; {*< Implements SDL_SendJoystickEffect() } + SetSensorsEnabled: function (userdata: Pointer; enabled: cbool): cbool; cdecl; {*< Implements SDL_SetGamepadSensorEnabled() } + Cleanup: procedure (userdata: Pointer); cdecl; {*< Cleans up the userdata when the joystick is detached } + end; + +{ Check the size of SDL_VirtualJoystickDesc + * + * If this assert fails, either the compiler is padding to an unexpected size, + * or the interface has been updated and this should be updated to match and + * the code using this interface should be updated to handle the old version. + } +{ #todo : SDL3-for-Pascal: Translate } +{SDL_COMPILE_TIME_ASSERT(SDL_VirtualJoystickDesc_SIZE,...} + +{* + * Attach a new virtual joystick. + * + * \param desc joystick description, initialized using SDL_INIT_INTERFACE(). + * \returns the joystick instance ID, or 0 on failure; call SDL_GetError() for + * more information. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_DetachVirtualJoystick + } +function SDL_AttachVirtualJoystick(desc: PSDL_VirtualJoystickDesc): TSDL_JoystickID; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_AttachVirtualJoystick' {$ENDIF} {$ENDIF}; + +{* + * Detach a virtual joystick. + * + * \param instance_id the joystick instance ID, previously returned from + * SDL_AttachVirtualJoystick(). + * \returns true on success or false on failure; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_AttachVirtualJoystick + } +function SDL_DetachVirtualJoystick(instance_id: TSDL_JoystickID): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_DetachVirtualJoystick' {$ENDIF} {$ENDIF}; + +{* + * Query whether or not a joystick is virtual. + * + * \param instance_id the joystick instance ID. + * \returns true if the joystick is virtual, false otherwise. + * + * \since This function is available since SDL 3.1.3. + } +function SDL_IsJoystickVirtual(instance_id: TSDL_JoystickID): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_IsJoystickVirtual' {$ENDIF} {$ENDIF}; + +{* + * Set the state of an axis on an opened virtual joystick. + * + * Please note that values set here will not be applied until the next call to + * SDL_UpdateJoysticks, which can either be called directly, or can be called + * indirectly through various other SDL APIs, including, but not limited to + * the following: SDL_PollEvent, SDL_PumpEvents, SDL_WaitEventTimeout, + * SDL_WaitEvent. + * + * Note that when sending trigger axes, you should scale the value to the full + * range of Sint16. For example, a trigger at rest would have the value of + * `SDL_JOYSTICK_AXIS_MIN`. + * + * \param joystick the virtual joystick on which to set state. + * \param axis the index of the axis on the virtual joystick to update. + * \param value the new value for the specified axis. + * \returns true on success or false on failure; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 3.1.3. + } +function SDL_SetJoystickVirtualAxis(joystick: PSDL_Joystick; axis: cint; value: cint16): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetJoystickVirtualAxis' {$ENDIF} {$ENDIF}; + +{* + * Generate ball motion on an opened virtual joystick. + * + * Please note that values set here will not be applied until the next call to + * SDL_UpdateJoysticks, which can either be called directly, or can be called + * indirectly through various other SDL APIs, including, but not limited to + * the following: SDL_PollEvent, SDL_PumpEvents, SDL_WaitEventTimeout, + * SDL_WaitEvent. + * + * \param joystick the virtual joystick on which to set state. + * \param ball the index of the ball on the virtual joystick to update. + * \param xrel the relative motion on the X axis. + * \param yrel the relative motion on the Y axis. + * \returns true on success or false on failure; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 3.1.3. + } +function SDL_SetJoystickVirtualBall(joystick: PSDL_Joystick; ball: cint; xrel: cint16; yrel: cint16): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetJoystickVirtualBall' {$ENDIF} {$ENDIF}; + +{* + * Set the state of a button on an opened virtual joystick. + * + * Please note that values set here will not be applied until the next call to + * SDL_UpdateJoysticks, which can either be called directly, or can be called + * indirectly through various other SDL APIs, including, but not limited to + * the following: SDL_PollEvent, SDL_PumpEvents, SDL_WaitEventTimeout, + * SDL_WaitEvent. + * + * \param joystick the virtual joystick on which to set state. + * \param button the index of the button on the virtual joystick to update. + * \param down true if the button is pressed, false otherwise. + * \returns true on success or false on failure; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 3.1.3. + } +function SDL_SetJoystickVirtualButton(joystick: PSDL_Joystick; button: cint; down: cbool): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetJoystickVirtualButton' {$ENDIF} {$ENDIF}; + +{* + * Set the state of a hat on an opened virtual joystick. + * + * Please note that values set here will not be applied until the next call to + * SDL_UpdateJoysticks, which can either be called directly, or can be called + * indirectly through various other SDL APIs, including, but not limited to + * the following: SDL_PollEvent, SDL_PumpEvents, SDL_WaitEventTimeout, + * SDL_WaitEvent. + * + * \param joystick the virtual joystick on which to set state. + * \param hat the index of the hat on the virtual joystick to update. + * \param value the new value for the specified hat. + * \returns true on success or false on failure; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 3.1.3. + } +function SDL_SetJoystickVirtualHat(joystick: PSDL_Joystick; hat: cint; value: cuint8): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetJoystickVirtualHat' {$ENDIF} {$ENDIF}; + +{* + * Set touchpad finger state on an opened virtual joystick. + * + * Please note that values set here will not be applied until the next call to + * SDL_UpdateJoysticks, which can either be called directly, or can be called + * indirectly through various other SDL APIs, including, but not limited to + * the following: SDL_PollEvent, SDL_PumpEvents, SDL_WaitEventTimeout, + * SDL_WaitEvent. + * + * \param joystick the virtual joystick on which to set state. + * \param touchpad the index of the touchpad on the virtual joystick to + * update. + * \param finger the index of the finger on the touchpad to set. + * \param down true if the finger is pressed, false if the finger is released. + * \param x the x coordinate of the finger on the touchpad, normalized 0 to 1, + * with the origin in the upper left. + * \param y the y coordinate of the finger on the touchpad, normalized 0 to 1, + * with the origin in the upper left. + * \param pressure the pressure of the finger. + * \returns true on success or false on failure; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 3.1.3. + } +function SDL_SetJoystickVirtualTouchpad(joystick: PSDL_Joystick; touchpad: cint; finger: cint; down: cbool; x: cfloat; + y: cfloat; pressure: cfloat): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetJoystickVirtualTouchpad' {$ENDIF} {$ENDIF}; + +{* + * Send a sensor update for an opened virtual joystick. + * + * Please note that values set here will not be applied until the next call to + * SDL_UpdateJoysticks, which can either be called directly, or can be called + * indirectly through various other SDL APIs, including, but not limited to + * the following: SDL_PollEvent, SDL_PumpEvents, SDL_WaitEventTimeout, + * SDL_WaitEvent. + * + * \param joystick the virtual joystick on which to set state. + * \param type the type of the sensor on the virtual joystick to update. + * \param sensor_timestamp a 64-bit timestamp in nanoseconds associated with + * the sensor reading. + * \param data the data associated with the sensor reading. + * \param num_values the number of values pointed to by `data`. + * \returns true on success or false on failure; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 3.1.3. + } +function SDL_SendJoystickVirtualSensorData(joystick: PSDL_Joystick; type_: TSDL_SensorType; sensor_timestamp: cuint64; data: pcfloat; num_values: cint): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SendJoystickVirtualSensorData' {$ENDIF} {$ENDIF}; + +{* + * Get the properties associated with a joystick. + * + * The following read-only properties are provided by SDL: + * + * - `SDL_PROP_JOYSTICK_CAP_MONO_LED_BOOLEAN`: true if this joystick has an + * LED that has adjustable brightness + * - `SDL_PROP_JOYSTICK_CAP_RGB_LED_BOOLEAN`: true if this joystick has an LED + * that has adjustable color + * - `SDL_PROP_JOYSTICK_CAP_PLAYER_LED_BOOLEAN`: true if this joystick has a + * player LED + * - `SDL_PROP_JOYSTICK_CAP_RUMBLE_BOOLEAN`: true if this joystick has + * left/right rumble + * - `SDL_PROP_JOYSTICK_CAP_TRIGGER_RUMBLE_BOOLEAN`: true if this joystick has + * simple trigger rumble + * + * \param joystick the SDL_Joystick obtained from SDL_OpenJoystick(). + * \returns a valid property ID on success or 0 on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 3.1.3. + } +function SDL_GetJoystickProperties(joystick: PSDL_Joystick): TSDL_PropertiesID; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetJoystickProperties' {$ENDIF} {$ENDIF}; + +const + SDL_PROP_JOYSTICK_CAP_MONO_LED_BOOLEAN = 'SDL.joystick.cap.mono_led'; + SDL_PROP_JOYSTICK_CAP_RGB_LED_BOOLEAN = 'SDL.joystick.cap.rgb_led'; + SDL_PROP_JOYSTICK_CAP_PLAYER_LED_BOOLEAN = 'SDL.joystick.cap.player_led'; + SDL_PROP_JOYSTICK_CAP_RUMBLE_BOOLEAN = 'SDL.joystick.cap.rumble'; + SDL_PROP_JOYSTICK_CAP_TRIGGER_RUMBLE_BOOLEAN = 'SDL.joystick.cap.trigger_rumble'; + +{* + * Get the implementation dependent name of a joystick. + * + * \param joystick the SDL_Joystick obtained from SDL_OpenJoystick(). + * \returns the name of the selected joystick. If no name can be found, this + * function returns nil; call SDL_GetError() for more information. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetJoystickNameForID + } +function SDL_GetJoystickName(joystick: PSDL_Joystick): PAnsiChar; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetJoystickName' {$ENDIF} {$ENDIF}; + +{* + * Get the implementation dependent path of a joystick. + * + * \param joystick the SDL_Joystick obtained from SDL_OpenJoystick(). + * \returns the path of the selected joystick. If no path can be found, this + * function returns nil; call SDL_GetError() for more information. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetJoystickPathForID + } +function SDL_GetJoystickPath(joystick: PSDL_Joystick): PAnsiChar; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetJoystickPath' {$ENDIF} {$ENDIF}; + +{* + * Get the player index of an opened joystick. + * + * For XInput controllers this returns the XInput user index. Many joysticks + * will not be able to supply this information. + * + * \param joystick the SDL_Joystick obtained from SDL_OpenJoystick(). + * \returns the player index, or -1 if it's not available. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_SetJoystickPlayerIndex + } +function SDL_GetJoystickPlayerIndex(joystick: PSDL_Joystick): cint; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetJoystickPlayerIndex' {$ENDIF} {$ENDIF}; + +{* + * Set the player index of an opened joystick. + * + * \param joystick the SDL_Joystick obtained from SDL_OpenJoystick(). + * \param player_index player index to assign to this joystick, or -1 to clear + * the player index and turn off player LEDs. + * \returns true on success or false on failure; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetJoystickPlayerIndex + } +function SDL_SetJoystickPlayerIndex(joystick: PSDL_Joystick; player_index: cint): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetJoystickPlayerIndex' {$ENDIF} {$ENDIF}; + +{* + * Get the implementation-dependent GUID for the joystick. + * + * This function requires an open joystick. + * + * \param joystick the SDL_Joystick obtained from SDL_OpenJoystick(). + * \returns the GUID of the given joystick. If called on an invalid index, + * this function returns a zero GUID; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetJoystickGUIDForID + * \sa SDL_GUIDToString + } +function SDL_GetJoystickGUID(joystick: PSDL_Joystick): TSDL_GUID; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetJoystickGUID' {$ENDIF} {$ENDIF}; + +{* + * Get the USB vendor ID of an opened joystick, if available. + * + * If the vendor ID isn't available this function returns 0. + * + * \param joystick the SDL_Joystick obtained from SDL_OpenJoystick(). + * \returns the USB vendor ID of the selected joystick, or 0 if unavailable. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetJoystickVendorForID + } +function SDL_GetJoystickVendor(joystick: PSDL_Joystick): cuint16; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetJoystickVendor' {$ENDIF} {$ENDIF}; + +{* + * Get the USB product ID of an opened joystick, if available. + * + * If the product ID isn't available this function returns 0. + * + * \param joystick the SDL_Joystick obtained from SDL_OpenJoystick(). + * \returns the USB product ID of the selected joystick, or 0 if unavailable. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetJoystickProductForID + } +function SDL_GetJoystickProduct(joystick: PSDL_Joystick): cuint16; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetJoystickProduct' {$ENDIF} {$ENDIF}; + +{* + * Get the product version of an opened joystick, if available. + * + * If the product version isn't available this function returns 0. + * + * \param joystick the SDL_Joystick obtained from SDL_OpenJoystick(). + * \returns the product version of the selected joystick, or 0 if unavailable. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetJoystickProductVersionForID + } +function SDL_GetJoystickProductVersion(joystick: PSDL_Joystick): cuint16; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetJoystickProductVersion' {$ENDIF} {$ENDIF}; + +{* + * Get the firmware version of an opened joystick, if available. + * + * If the firmware version isn't available this function returns 0. + * + * \param joystick the SDL_Joystick obtained from SDL_OpenJoystick(). + * \returns the firmware version of the selected joystick, or 0 if + * unavailable. + * + * \since This function is available since SDL 3.1.3. + } +function SDL_GetJoystickFirmwareVersion(joystick: PSDL_Joystick): cuint16; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetJoystickFirmwareVersion' {$ENDIF} {$ENDIF}; + +{* + * Get the serial number of an opened joystick, if available. + * + * Returns the serial number of the joystick, or nil if it is not available. + * + * \param joystick the SDL_Joystick obtained from SDL_OpenJoystick(). + * \returns the serial number of the selected joystick, or nil if + * unavailable. + * + * \since This function is available since SDL 3.1.3. + } +function SDL_GetJoystickSerial(joystick: PSDL_Joystick): PAnsiChar; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetJoystickSerial' {$ENDIF} {$ENDIF}; + +{* + * Get the type of an opened joystick. + * + * \param joystick the SDL_Joystick obtained from SDL_OpenJoystick(). + * \returns the SDL_JoystickType of the selected joystick. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetJoystickTypeForID + } +function SDL_GetJoystickType(joystick: PSDL_Joystick): TSDL_JoystickType; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetJoystickType' {$ENDIF} {$ENDIF}; + +{* + * Get the device information encoded in a SDL_GUID structure. + * + * \param guid the SDL_GUID you wish to get info about. + * \param vendor a Pointer filled in with the device VID, or 0 if not + * available. + * \param product a Pointer filled in with the device PID, or 0 if not + * available. + * \param version a Pointer filled in with the device version, or 0 if not + * available. + * \param crc16 a Pointer filled in with a CRC used to distinguish different + * products with the same VID/PID, or 0 if not available. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetJoystickGUIDForID + } +procedure SDL_GetJoystickGUIDInfo(guid: TSDL_GUID; vendor: pcuint16; product: pcuint16; version: pcuint16; crc16: pcuint16); cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetJoystickGUIDInfo' {$ENDIF} {$ENDIF}; + +{* + * Get the status of a specified joystick. + * + * \param joystick the joystick to query. + * \returns true if the joystick has been opened, false if it has not; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 3.1.3. + } +function SDL_JoystickConnected(joystick: PSDL_Joystick): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_JoystickConnected' {$ENDIF} {$ENDIF}; + +{* + * Get the instance ID of an opened joystick. + * + * \param joystick an SDL_Joystick structure containing joystick information. + * \returns the instance ID of the specified joystick on success or 0 on + * failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 3.1.3. + } +function SDL_GetJoystickID(joystick: PSDL_Joystick): TSDL_JoystickID; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetJoystickID' {$ENDIF} {$ENDIF}; + +{* + * Get the number of general axis controls on a joystick. + * + * Often, the directional pad on a game controller will either look like 4 + * separate buttons or a POV hat, and not axes, but all of this is up to the + * device and platform. + * + * \param joystick an SDL_Joystick structure containing joystick information. + * \returns the number of axis controls/number of axes on success or -1 on + * failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetJoystickAxis + * \sa SDL_GetNumJoystickBalls + * \sa SDL_GetNumJoystickButtons + * \sa SDL_GetNumJoystickHats + } +function SDL_GetNumJoystickAxes(joystick: PSDL_Joystick): cint; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetNumJoystickAxes' {$ENDIF} {$ENDIF}; + +{* + * Get the number of trackballs on a joystick. + * + * Joystick trackballs have only relative motion events associated with them + * and their state cannot be polled. + * + * Most joysticks do not have trackballs. + * + * \param joystick an SDL_Joystick structure containing joystick information. + * \returns the number of trackballs on success or -1 on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetJoystickBall + * \sa SDL_GetNumJoystickAxes + * \sa SDL_GetNumJoystickButtons + * \sa SDL_GetNumJoystickHats + } +function SDL_GetNumJoystickBalls(joystick: PSDL_Joystick): cint; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetNumJoystickBalls' {$ENDIF} {$ENDIF}; + +{* + * Get the number of POV hats on a joystick. + * + * \param joystick an SDL_Joystick structure containing joystick information. + * \returns the number of POV hats on success or -1 on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetJoystickHat + * \sa SDL_GetNumJoystickAxes + * \sa SDL_GetNumJoystickBalls + * \sa SDL_GetNumJoystickButtons + } +function SDL_GetNumJoystickHats(joystick: PSDL_Joystick): cint; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetNumJoystickHats' {$ENDIF} {$ENDIF}; + +{* + * Get the number of buttons on a joystick. + * + * \param joystick an SDL_Joystick structure containing joystick information. + * \returns the number of buttons on success or -1 on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetJoystickButton + * \sa SDL_GetNumJoystickAxes + * \sa SDL_GetNumJoystickBalls + * \sa SDL_GetNumJoystickHats + } +function SDL_GetNumJoystickButtons(joystick: PSDL_Joystick): cint; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetNumJoystickButtons' {$ENDIF} {$ENDIF}; + +{* + * Set the state of joystick event processing. + * + * If joystick events are disabled, you must call SDL_UpdateJoysticks() + * yourself and check the state of the joystick when you want joystick + * information. + * + * \param enabled whether to process joystick events or not. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_JoystickEventsEnabled + * \sa SDL_UpdateJoysticks + } +procedure SDL_SetJoystickEventsEnabled(enabled: cbool); cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetJoystickEventsEnabled' {$ENDIF} {$ENDIF}; + +{* + * Query the state of joystick event processing. + * + * If joystick events are disabled, you must call SDL_UpdateJoysticks() + * yourself and check the state of the joystick when you want joystick + * information. + * + * \returns true if joystick events are being processed, false otherwise. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_SetJoystickEventsEnabled + } +function SDL_JoystickEventsEnabled: cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_JoystickEventsEnabled' {$ENDIF} {$ENDIF}; + +{* + * Update the current state of the open joysticks. + * + * This is called automatically by the event loop if any joystick events are + * enabled. + * + * \since This function is available since SDL 3.1.3. + } +procedure SDL_UpdateJoysticks; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_UpdateJoysticks' {$ENDIF} {$ENDIF}; + +{* + * Get the current state of an axis control on a joystick. + * + * SDL makes no promises about what part of the joystick any given axis refers + * to. Your game should have some sort of configuration UI to let users + * specify what each axis should be bound to. Alternately, SDL's higher-level + * Game Controller API makes a great effort to apply order to this lower-level + * interface, so you know that a specific axis is the "left thumb stick," etc. + * + * The value returned by SDL_GetJoystickAxis() is a signed integer (-32768 to + * 32767) representing the current position of the axis. It may be necessary + * to impose certain tolerances on these values to account for jitter. + * + * \param joystick an SDL_Joystick structure containing joystick information. + * \param axis the axis to query; the axis indices start at index 0. + * \returns a 16-bit signed integer representing the current position of the + * axis or 0 on failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetNumJoystickAxes + } +function SDL_GetJoystickAxis(joystick: PSDL_Joystick; axis: cint): cint16; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetJoystickAxis' {$ENDIF} {$ENDIF}; + +{* + * Get the initial state of an axis control on a joystick. + * + * The state is a value ranging from -32768 to 32767. + * + * The axis indices start at index 0. + * + * \param joystick an SDL_Joystick structure containing joystick information. + * \param axis the axis to query; the axis indices start at index 0. + * \param state upon return, the initial value is supplied here. + * \returns true if this axis has any initial value, or false if not. + * + * \since This function is available since SDL 3.1.3. + } +function SDL_GetJoystickAxisInitialState(joystick: PSDL_Joystick; axis: cint; state: pcint16): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetJoystickAxisInitialState' {$ENDIF} {$ENDIF}; + +{* + * Get the ball axis change since the last poll. + * + * Trackballs can only return relative motion since the last call to + * SDL_GetJoystickBall(), these motion deltas are placed into `dx` and `dy`. + * + * Most joysticks do not have trackballs. + * + * \param joystick the SDL_Joystick to query. + * \param ball the ball index to query; ball indices start at index 0. + * \param dx stores the difference in the x axis position since the last poll. + * \param dy stores the difference in the y axis position since the last poll. + * \returns true on success or false on failure; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetNumJoystickBalls + } +function SDL_GetJoystickBall(joystick: PSDL_Joystick; ball: cint; dx: pcint; dy: pcint): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetJoystickBall' {$ENDIF} {$ENDIF}; + +{* + * Get the current state of a POV hat on a joystick. + * + * The returned value will be one of the `SDL_HAT_*` values. + * + * \param joystick an SDL_Joystick structure containing joystick information. + * \param hat the hat index to get the state from; indices start at index 0. + * \returns the current hat position. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetNumJoystickHats + } +function SDL_GetJoystickHat(joystick: PSDL_Joystick; hat: cint): cuint8; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetJoystickHat' {$ENDIF} {$ENDIF}; + +const + SDL_HAT_CENTERED = $00; + SDL_HAT_UP = $01; + SDL_HAT_RIGHT = $02; + SDL_HAT_DOWN = $04; + SDL_HAT_LEFT = $08; + SDL_HAT_RIGHTUP = SDL_HAT_RIGHT or SDL_HAT_UP; + SDL_HAT_RIGHTDOWN = SDL_HAT_RIGHT or SDL_HAT_DOWN; + SDL_HAT_LEFTUP = SDL_HAT_LEFT or SDL_HAT_UP; + SDL_HAT_LEFTDOWN = SDL_HAT_LEFT or SDL_HAT_DOWN; + +{* + * Get the current state of a button on a joystick. + * + * \param joystick an SDL_Joystick structure containing joystick information. + * \param button the button index to get the state from; indices start at + * index 0. + * \returns true if the button is pressed, false otherwise. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetNumJoystickButtons + } +function SDL_GetJoystickButton(joystick: PSDL_Joystick; button: cint): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetJoystickButton' {$ENDIF} {$ENDIF}; + +{* + * Start a rumble effect. + * + * Each call to this function cancels any previous rumble effect, and calling + * it with 0 intensity stops any rumbling. + * + * This function requires you to process SDL events or call + * SDL_UpdateJoysticks() to update rumble state. + * + * \param joystick the joystick to vibrate. + * \param low_frequency_rumble the intensity of the low frequency (left) + * rumble motor, from 0 to 0xFFFF. + * \param high_frequency_rumble the intensity of the high frequency (right) + * rumble motor, from 0 to 0xFFFF. + * \param duration_ms the duration of the rumble effect, in milliseconds. + * \returns true, or false if rumble isn't supported on this joystick. + * + * \since This function is available since SDL 3.1.3. + } +function SDL_RumbleJoystick(joystick: PSDL_Joystick; low_frequency_rumble: cuint16; high_frequency_rumble: cuint16; duration_ms: cuint32): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RumbleJoystick' {$ENDIF} {$ENDIF}; + +{* + * Start a rumble effect in the joystick's triggers. + * + * Each call to this function cancels any previous trigger rumble effect, and + * calling it with 0 intensity stops any rumbling. + * + * Note that this is rumbling of the _triggers_ and not the game controller as + * a whole. This is currently only supported on Xbox One controllers. If you + * want the (more common) whole-controller rumble, use SDL_RumbleJoystick() + * instead. + * + * This function requires you to process SDL events or call + * SDL_UpdateJoysticks() to update rumble state. + * + * \param joystick the joystick to vibrate. + * \param left_rumble the intensity of the left trigger rumble motor, from 0 + * to 0xFFFF. + * \param right_rumble the intensity of the right trigger rumble motor, from 0 + * to 0xFFFF. + * \param duration_ms the duration of the rumble effect, in milliseconds. + * \returns true on success or false on failure; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_RumbleJoystick + } +function SDL_RumbleJoystickTriggers(joystick: PSDL_Joystick; left_rumble: cuint16; right_rumble: cuint16; duration_ms: cuint32): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_RumbleJoystickTriggers' {$ENDIF} {$ENDIF}; + +{* + * Update a joystick's LED color. + * + * An example of a joystick LED is the light on the back of a PlayStation 4's + * DualShock 4 controller. + * + * For joysticks with a single color LED, the maximum of the RGB values will + * be used as the LED brightness. + * + * \param joystick the joystick to update. + * \param red the intensity of the red LED. + * \param green the intensity of the green LED. + * \param blue the intensity of the blue LED. + * \returns true on success or false on failure; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 3.1.3. + } +function SDL_SetJoystickLED(joystick: PSDL_Joystick; red: cuint8; green: cuint8; blue: cuint8): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetJoystickLED' {$ENDIF} {$ENDIF}; + +{* + * Send a joystick specific effect packet. + * + * \param joystick the joystick to affect. + * \param data the data to send to the joystick. + * \param size the size of the data to send to the joystick. + * \returns true on success or false on failure; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 3.1.3. + } +function SDL_SendJoystickEffect(joystick: PSDL_Joystick; data: Pointer; size: cint): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SendJoystickEffect' {$ENDIF} {$ENDIF}; + +{* + * Close a joystick previously opened with SDL_OpenJoystick(). + * + * \param joystick the joystick device to close. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_OpenJoystick + } +procedure SDL_CloseJoystick(joystick: PSDL_Joystick); cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_CloseJoystick' {$ENDIF} {$ENDIF}; + +{* + * Get the connection state of a joystick. + * + * \param joystick the joystick to query. + * \returns the connection state on success or + * `SDL_JOYSTICK_CONNECTION_INVALID` on failure; call SDL_GetError() + * for more information. + * + * \since This function is available since SDL 3.1.3. + } +function SDL_GetJoystickConnectionState(joystick: PSDL_Joystick): TSDL_JoystickConnectionState; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetJoystickConnectionState' {$ENDIF} {$ENDIF}; + +{* + * Get the battery state of a joystick. + * + * You should never take a battery status as absolute truth. Batteries + * (especially failing batteries) are delicate hardware, and the values + * reported here are best estimates based on what that hardware reports. It's + * not uncommon for older batteries to lose stored power much faster than it + * reports, or completely drain when reporting it has 20 percent left, etc. + * + * \param joystick the joystick to query. + * \param percent a Pointer filled in with the percentage of battery life + * left, between 0 and 100, or nil to ignore. This will be + * filled in with -1 we can't determine a value or there is no + * battery. + * \returns the current battery state or `SDL_POWERSTATE_ERROR` on failure; + * call SDL_GetError() for more information. + * + * \since This function is available since SDL 3.1.3. + } +function SDL_GetJoystickPowerInfo(joystick: PSDL_Joystick; percent: pcint): TSDL_PowerState; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetJoystickPowerInfo' {$ENDIF} {$ENDIF}; + diff --git a/units/SDL_keyboard.inc b/units/SDL_keyboard.inc new file mode 100644 index 0000000..159f086 --- /dev/null +++ b/units/SDL_keyboard.inc @@ -0,0 +1,551 @@ +{ + This file is part of: + + SDL3 for Pascal + (https://github.com/PascalGameDevelopment/SDL3-for-Pascal) + SPDX-License-Identifier: Zlib +} + +{* + * # CategoryKeyboard + * + * SDL keyboard management. + } + +{* + * This is a unique ID for a keyboard for the time it is connected to the + * system, and is never reused for the lifetime of the application. + * + * If the keyboard is disconnected and reconnected, it will get a new ID. + * + * The value 0 is an invalid ID. + * + * \since This datatype is available since SDL 3.1.3. + } +type + PPSDL_KeyboardID = ^PSDL_KeyboardID; + PSDL_KeyboardID = ^TSDL_KeyboardID; + TSDL_KeyboardID = cuint32; + +{ Function prototypes } + +{* + * Return whether a keyboard is currently connected. + * + * \returns true if a keyboard is connected, false otherwise. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetKeyboards + } +function SDL_HasKeyboard: cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HasKeyboard' {$ENDIF} {$ENDIF}; + +{* + * Get a list of currently connected keyboards. + * + * Note that this will include any device or virtual driver that includes + * keyboard functionality, including some mice, KVM switches, motherboard + * power buttons, etc. You should wait for input from a device before you + * consider it actively in use. + * + * \param count a Pointer filled in with the number of keyboards returned, may + * be nil. + * \returns a 0 terminated array of keyboards instance IDs or nil on failure; + * call SDL_GetError() for more information. This should be freed + * with SDL_free() when it is no longer needed. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetKeyboardNameForID + * \sa SDL_HasKeyboard + } +function SDL_GetKeyboards(count: pcint): PSDL_KeyboardID; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetKeyboards' {$ENDIF} {$ENDIF}; + +{* + * Get the name of a keyboard. + * + * This function returns "" if the keyboard doesn't have a name. + * + * \param instance_id the keyboard instance ID. + * \returns the name of the selected keyboard or nil on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetKeyboards + } +function SDL_GetKeyboardNameForID(instance_id: TSDL_KeyboardID): PAnsiChar; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetKeyboardNameForID' {$ENDIF} {$ENDIF}; + +{* + * Query the window which currently has keyboard focus. + * + * \returns the window with keyboard focus. + * + * \since This function is available since SDL 3.1.3. + } +function SDL_GetKeyboardFocus: PSDL_Window; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetKeyboardFocus' {$ENDIF} {$ENDIF}; + +{* + * Get a snapshot of the current state of the keyboard. + * + * The Pointer returned is a Pointer to an internal SDL array. It will be + * valid for the whole lifetime of the application and should not be freed by + * the caller. + * + * A array element with a value of true means that the key is pressed and a + * value of false means that it is not. Indexes into this array are obtained + * by using SDL_Scancode values. + * + * Use SDL_PumpEvents() to update the state array. + * + * This function gives you the current state after all events have been + * processed, so if a key or button has been pressed and released before you + * process events, then the pressed state will never show up in the + * SDL_GetKeyboardState() calls. + * + * Note: This function doesn't take into account whether shift has been + * pressed or not. + * + * \param numkeys if non-nil, receives the length of the returned array. + * \returns a Pointer to an array of key states. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_PumpEvents + * \sa SDL_ResetKeyboard + } +function SDL_GetKeyboardState(numkeys: pcint): pcbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetKeyboardState' {$ENDIF} {$ENDIF}; + +{* + * Clear the state of the keyboard. + * + * This function will generate key up events for all pressed keys. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetKeyboardState + } +procedure SDL_ResetKeyboard; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_ResetKeyboard' {$ENDIF} {$ENDIF}; + +{* + * Get the current key modifier state for the keyboard. + * + * \returns an OR'd combination of the modifier keys for the keyboard. See + * SDL_Keymod for details. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetKeyboardState + * \sa SDL_SetModState + } +function SDL_GetModState: TSDL_Keymod; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetModState' {$ENDIF} {$ENDIF}; + +{* + * Set the current key modifier state for the keyboard. + * + * The inverse of SDL_GetModState(), SDL_SetModState() allows you to impose + * modifier key states on your application. Simply pass your desired modifier + * states into `modstate`. This value may be a bitwise, OR'd combination of + * SDL_Keymod values. + * + * This does not change the keyboard state, only the key modifier flags that + * SDL reports. + * + * \param modstate the desired SDL_Keymod for the keyboard. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetModState + } +procedure SDL_SetModState(modstate: TSDL_Keymod); cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetModState' {$ENDIF} {$ENDIF}; + +{* + * Get the key code corresponding to the given scancode according to the + * current keyboard layout. + * + * If you want to get the keycode as it would be delivered in key events, + * including options specified in SDL_HINT_KEYCODE_OPTIONS, then you should + * pass `key_event` as true. Otherwise this function simply translates the + * scancode based on the given modifier state. + * + * \param scancode the desired SDL_Scancode to query. + * \param modstate the modifier state to use when translating the scancode to + * a keycode. + * \param key_event true if the keycode will be used in key events. + * \returns the SDL_Keycode that corresponds to the given SDL_Scancode. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetKeyName + * \sa SDL_GetScancodeFromKey + } +function SDL_GetKeyFromScancode(scancode: TSDL_Scancode; modstate: TSDL_Keymod; key_event: cbool): TSDL_Keycode; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetKeyFromScancode' {$ENDIF} {$ENDIF}; + +{* + * Get the scancode corresponding to the given key code according to the + * current keyboard layout. + * + * Note that there may be multiple scancode+modifier states that can generate + * this keycode, this will just return the first one found. + * + * \param key the desired SDL_Keycode to query. + * \param modstate a Pointer to the modifier state that would be used when the + * scancode generates this key, may be nil. + * \returns the SDL_Scancode that corresponds to the given SDL_Keycode. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetKeyFromScancode + * \sa SDL_GetScancodeName + } +function SDL_GetScancodeFromKey(key: TSDL_Keycode; modstate: PSDL_Keymod): TSDL_Scancode; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetScancodeFromKey' {$ENDIF} {$ENDIF}; + +{* + * Set a human-readable name for a scancode. + * + * \param scancode the desired SDL_Scancode. + * \param name the name to use for the scancode, encoded as UTF-8. The string + * is not copied, so the Pointer given to this function must stay + * valid while SDL is being used. + * \returns true on success or false on failure; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetScancodeName + } +function SDL_SetScancodeName(scancode: TSDL_Scancode; name: PAnsiChar): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetScancodeName' {$ENDIF} {$ENDIF}; + +{* + * Get a human-readable name for a scancode. + * + * **Warning**: The returned name is by design not stable across platforms, + * e.g. the name for `SDL_SCANCODE_LGUI` is "Left GUI" under Linux but "Left + * Windows" under Microsoft Windows, and some scancodes like + * `SDL_SCANCODE_NONUSBACKSLASH` don't have any name at all. There are even + * scancodes that share names, e.g. `SDL_SCANCODE_RETURN` and + * `SDL_SCANCODE_RETURN2` (both called "Return"). This function is therefore + * unsuitable for creating a stable cross-platform two-way mapping between + * strings and scancodes. + * + * \param scancode the desired SDL_Scancode to query. + * \returns a Pointer to the name for the scancode. If the scancode doesn't + * have a name this function returns an empty string (""). + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetScancodeFromKey + * \sa SDL_GetScancodeFromName + * \sa SDL_SetScancodeName + } +function SDL_GetScancodeName(scancode: TSDL_Scancode): PAnsiChar; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetScancodeName' {$ENDIF} {$ENDIF}; + +{* + * Get a scancode from a human-readable name. + * + * \param name the human-readable scancode name. + * \returns the SDL_Scancode, or `SDL_SCANCODE_UNKNOWN` if the name wasn't + * recognized; call SDL_GetError() for more information. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetKeyFromName + * \sa SDL_GetScancodeFromKey + * \sa SDL_GetScancodeName + } +function SDL_GetScancodeFromName(name: PAnsiChar): TSDL_Scancode; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetScancodeFromName' {$ENDIF} {$ENDIF}; + +{* + * Get a human-readable name for a key. + * + * If the key doesn't have a name, this function returns an empty string (""). + * + * \param key the desired SDL_Keycode to query. + * \returns a UTF-8 encoded string of the key name. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetKeyFromName + * \sa SDL_GetKeyFromScancode + * \sa SDL_GetScancodeFromKey + } +function SDL_GetKeyName(key: TSDL_Keycode): PAnsiChar; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetKeyName' {$ENDIF} {$ENDIF}; + +{* + * Get a key code from a human-readable name. + * + * \param name the human-readable key name. + * \returns key code, or `SDLK_UNKNOWN` if the name wasn't recognized; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetKeyFromScancode + * \sa SDL_GetKeyName + * \sa SDL_GetScancodeFromName + } +function SDL_GetKeyFromName(name: PAnsiChar): TSDL_Keycode; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetKeyFromName' {$ENDIF} {$ENDIF}; + +{* + * Start accepting Unicode text input events in a window. + * + * This function will enable text input (SDL_EVENT_TEXT_INPUT and + * SDL_EVENT_TEXT_EDITING events) in the specified window. Please use this + * function paired with SDL_StopTextInput(). + * + * Text input events are not received by default. + * + * On some platforms using this function shows the screen keyboard and/or + * activates an IME, which can prevent some key press events from being passed + * through. + * + * \param window the window to enable text input. + * \returns true on success or false on failure; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_SetTextInputArea + * \sa SDL_StartTextInputWithProperties + * \sa SDL_StopTextInput + * \sa SDL_TextInputActive + } +function SDL_StartTextInput(window: PSDL_Window): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_StartTextInput' {$ENDIF} {$ENDIF}; + +{* + * Text input type. + * + * These are the valid values for SDL_PROP_TEXTINPUT_TYPE_NUMBER. Not every + * value is valid on every platform, but where a value isn't supported, a + * reasonable fallback will be used. + * + * \since This enum is available since SDL 3.1.3. + * + * \sa SDL_StartTextInputWithProperties + } +type + PPSDL_TextInputType = ^PSDL_TextInputType; + PSDL_TextInputType = ^TSDL_TextInputType; + TSDL_TextInputType = type Integer; +const + SDL_TEXTINPUT_TYPE_TEXT = TSDL_TextInputType(0); {*< The input is text } + SDL_TEXTINPUT_TYPE_TEXT_NAME = TSDL_TextInputType(1); {*< The input is a person's name } + SDL_TEXTINPUT_TYPE_TEXT_EMAIL = TSDL_TextInputType(2); {*< The input is an e-mail address } + SDL_TEXTINPUT_TYPE_TEXT_USERNAME = TSDL_TextInputType(3); {*< The input is a username } + SDL_TEXTINPUT_TYPE_TEXT_PASSWORD_HIDDEN = TSDL_TextInputType(4); {*< The input is a secure password that is hidden } + SDL_TEXTINPUT_TYPE_TEXT_PASSWORD_VISIBLE = TSDL_TextInputType(5); {*< The input is a secure password that is visible } + SDL_TEXTINPUT_TYPE_NUMBER = TSDL_TextInputType(6); {*< The input is a number } + SDL_TEXTINPUT_TYPE_NUMBER_PASSWORD_HIDDEN = TSDL_TextInputType(7); {*< The input is a secure PIN that is hidden } + SDL_TEXTINPUT_TYPE_NUMBER_PASSWORD_VISIBLE = TSDL_TextInputType(8); {*< The input is a secure PIN that is visible } + +{* + * Auto capitalization type. + * + * These are the valid values for + * SDL_PROP_TEXTINPUT_AUTOCAPITALIZATION_NUMBER. Not every value is valid on + * every platform, but where a value isn't supported, a reasonable fallback + * will be used. + * + * \since This enum is available since SDL 3.1.3. + * + * \sa SDL_StartTextInputWithProperties + } +type + PPSDL_Capitalization = ^PSDL_Capitalization; + PSDL_Capitalization = ^TSDL_Capitalization; + TSDL_Capitalization = type Integer; +const + SDL_CAPITALIZE_NONE = TSDL_Capitalization(0); {*< No auto-capitalization will be done } + SDL_CAPITALIZE_SENTENCES = TSDL_Capitalization(1); {*< The first letter of sentences will be capitalized } + SDL_CAPITALIZE_WORDS = TSDL_Capitalization(2); {*< The first letter of words will be capitalized } + SDL_CAPITALIZE_LETTERS = TSDL_Capitalization(3); {*< All letters will be capitalized } + +{* + * Start accepting Unicode text input events in a window, with properties + * describing the input. + * + * This function will enable text input (SDL_EVENT_TEXT_INPUT and + * SDL_EVENT_TEXT_EDITING events) in the specified window. Please use this + * function paired with SDL_StopTextInput(). + * + * Text input events are not received by default. + * + * On some platforms using this function shows the screen keyboard and/or + * activates an IME, which can prevent some key press events from being passed + * through. + * + * These are the supported properties: + * + * - `SDL_PROP_TEXTINPUT_TYPE_NUMBER` - an SDL_TextInputType value that + * describes text being input, defaults to SDL_TEXTINPUT_TYPE_TEXT. + * - `SDL_PROP_TEXTINPUT_CAPITALIZATION_NUMBER` - an SDL_Capitalization value + * that describes how text should be capitalized, defaults to + * SDL_CAPITALIZE_SENTENCES for normal text entry, SDL_CAPITALIZE_WORDS for + * SDL_TEXTINPUT_TYPE_TEXT_NAME, and SDL_CAPITALIZE_NONE for e-mail + * addresses, usernames, and passwords. + * - `SDL_PROP_TEXTINPUT_AUTOCORRECT_BOOLEAN` - true to enable auto completion + * and auto correction, defaults to true. + * - `SDL_PROP_TEXTINPUT_MULTILINE_BOOLEAN` - true if multiple lines of text + * are allowed. This defaults to true if SDL_HINT_RETURN_KEY_HIDES_IME is + * "0" or is not set, and defaults to false if SDL_HINT_RETURN_KEY_HIDES_IME + * is "1". + * + * On Android you can directly specify the input type: + * + * - `SDL_PROP_TEXTINPUT_ANDROID_INPUTTYPE_NUMBER` - the text input type to + * use, overriding other properties. This is documented at + * https://developer.android.com/reference/android/text/InputType + * + * \param window the window to enable text input. + * \param props the properties to use. + * \returns true on success or false on failure; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_SetTextInputArea + * \sa SDL_StartTextInput + * \sa SDL_StopTextInput + * \sa SDL_TextInputActive + } +function SDL_StartTextInputWithProperties(window: PSDL_Window; props: TSDL_PropertiesID): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_StartTextInputWithProperties' {$ENDIF} {$ENDIF}; + + const + SDL_PROP_TEXTINPUT_TYPE_NUMBER = 'SDL.textinput.type'; + SDL_PROP_TEXTINPUT_CAPITALIZATION_NUMBER = 'SDL.textinput.capitalization'; + SDL_PROP_TEXTINPUT_AUTOCORRECT_BOOLEAN = 'SDL.textinput.autocorrect'; + SDL_PROP_TEXTINPUT_MULTILINE_BOOLEAN = 'SDL.textinput.multiline'; + SDL_PROP_TEXTINPUT_ANDROID_INPUTTYPE_NUMBER = 'SDL.textinput.android.inputtype'; + +{* + * Check whether or not Unicode text input events are enabled for a window. + * + * \param window the window to check. + * \returns true if text input events are enabled else false. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_StartTextInput + } +function SDL_TextInputActive(window: PSDL_Window): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_TextInputActive' {$ENDIF} {$ENDIF}; + +{* + * Stop receiving any text input events in a window. + * + * If SDL_StartTextInput() showed the screen keyboard, this function will hide + * it. + * + * \param window the window to disable text input. + * \returns true on success or false on failure; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_StartTextInput + } +function SDL_StopTextInput(window: PSDL_Window): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_StopTextInput' {$ENDIF} {$ENDIF}; + +{* + * Dismiss the composition window/IME without disabling the subsystem. + * + * \param window the window to affect. + * \returns true on success or false on failure; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_StartTextInput + * \sa SDL_StopTextInput + } +function SDL_ClearComposition(window: PSDL_Window): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_ClearComposition' {$ENDIF} {$ENDIF}; + +{* + * Set the area used to type Unicode text input. + * + * Native input methods may place a window with word suggestions near the + * cursor, without covering the text being entered. + * + * \param window the window for which to set the text input area. + * \param rect the SDL_Rect representing the text input area, in window + * coordinates, or nil to clear it. + * \param cursor the offset of the current cursor location relative to + * `rect->x`, in window coordinates. + * \returns true on success or false on failure; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetTextInputArea + * \sa SDL_StartTextInput + } + +function SDL_SetTextInputArea(window: PSDL_Window; rect: PSDL_Rect; cursor: cint): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetTextInputArea' {$ENDIF} {$ENDIF}; + +{* + * Get the area used to type Unicode text input. + * + * This returns the values previously set by SDL_SetTextInputArea(). + * + * \param window the window for which to query the text input area. + * \param rect a Pointer to an SDL_Rect filled in with the text input area, + * may be nil. + * \param cursor a Pointer to the offset of the current cursor location + * relative to `rect->x`, may be nil. + * \returns true on success or false on failure; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_SetTextInputArea + } +function SDL_GetTextInputArea(window: PSDL_Window; rect: PSDL_Rect; cursor: pcint): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetTextInputArea' {$ENDIF} {$ENDIF}; + +{* + * Check whether the platform has screen keyboard support. + * + * \returns true if the platform has some screen keyboard support or false if + * not. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_StartTextInput + * \sa SDL_ScreenKeyboardShown + } +function SDL_HasScreenKeyboardSupport: cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HasScreenKeyboardSupport' {$ENDIF} {$ENDIF}; + +{* + * Check whether the screen keyboard is shown for given window. + * + * \param window the window for which screen keyboard should be queried. + * \returns true if screen keyboard is shown or false if not. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_HasScreenKeyboardSupport + } +function SDL_ScreenKeyboardShown(window: PSDL_Window): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_ScreenKeyboardShown' {$ENDIF} {$ENDIF}; + diff --git a/units/SDL_keycode.inc b/units/SDL_keycode.inc new file mode 100644 index 0000000..f590da3 --- /dev/null +++ b/units/SDL_keycode.inc @@ -0,0 +1,315 @@ +{ + This file is part of: + + SDL3 for Pascal + (https://github.com/PascalGameDevelopment/SDL3-for-Pascal) + SPDX-License-Identifier: Zlib +} + +{* + * # CategoryKeycode + * + * Defines constants which identify keyboard keys and modifiers. + } + +{* + * The SDL virtual key representation. + * + * Values of this type are used to represent keyboard keys using the current + * layout of the keyboard. These values include Unicode values representing + * the unmodified character that would be generated by pressing the key, or an + * `SDLK_*` constant for those keys that do not generate characters. + * + * A special exception is the number keys at the top of the keyboard which map + * to SDLK_0...SDLK_9 on AZERTY layouts. + * + * \since This datatype is available since SDL 3.1.3. + } +type + PPSDL_Keycode = ^PSDL_Keycode; + PSDL_Keycode = ^TSDL_Keycode; + TSDL_Keycode = type cuint32; + +const + SDLK_SCANCODE_MASK = 1 shl 30; +function SDL_SCANCODE_TO_KEYCODE(X: TSDL_Scancode): TSDL_Keycode; {SDL3-for-Pascal: C Macro} +const + SDLK_UNKNOWN = TSDL_Keycode($00000000); {*< 0 } + SDLK_RETURN = TSDL_Keycode($0000000d); {*< '\r' } + SDLK_ESCAPE = TSDL_Keycode($0000001b); {*< '\x1B' } + SDLK_BACKSPACE = TSDL_Keycode($00000008); {*< '\b' } + SDLK_TAB = TSDL_Keycode($00000009); {*< '\t' } + SDLK_SPACE = TSDL_Keycode($00000020); {*< ' ' } + SDLK_EXCLAIM = TSDL_Keycode($00000021); {*< '!' } + SDLK_DBLAPOSTROPHE = TSDL_Keycode($00000022); {*< '"' } + SDLK_HASH = TSDL_Keycode($00000023); {*< '#' } + SDLK_DOLLAR = TSDL_Keycode($00000024); {*< '$' } + SDLK_PERCENT = TSDL_Keycode($00000025); {*< '%' } + SDLK_AMPERSAND = TSDL_Keycode($00000026); {*< '&' } + SDLK_APOSTROPHE = TSDL_Keycode($00000027); {*< '\'' } + SDLK_LEFTPAREN = TSDL_Keycode($00000028); {*< '(' } + SDLK_RIGHTPAREN = TSDL_Keycode($00000029); {*< ')' } + SDLK_ASTERISK = TSDL_Keycode($0000002a); {*< '*' } + SDLK_PLUS = TSDL_Keycode($0000002b); {*< '+' } + SDLK_COMMA = TSDL_Keycode($0000002c); {*< ',' } + SDLK_MINUS = TSDL_Keycode($0000002d); {*< '-' } + SDLK_PERIOD = TSDL_Keycode($0000002e); {*< '.' } + SDLK_SLASH = TSDL_Keycode($0000002f); {*< '/' } + SDLK_0 = TSDL_Keycode($00000030); {*< '0' } + SDLK_1 = TSDL_Keycode($00000031); {*< '1' } + SDLK_2 = TSDL_Keycode($00000032); {*< '2' } + SDLK_3 = TSDL_Keycode($00000033); {*< '3' } + SDLK_4 = TSDL_Keycode($00000034); {*< '4' } + SDLK_5 = TSDL_Keycode($00000035); {*< '5' } + SDLK_6 = TSDL_Keycode($00000036); {*< '6' } + SDLK_7 = TSDL_Keycode($00000037); {*< '7' } + SDLK_8 = TSDL_Keycode($00000038); {*< '8' } + SDLK_9 = TSDL_Keycode($00000039); {*< '9' } + SDLK_COLON = TSDL_Keycode($0000003a); {*< ':' } + SDLK_SEMICOLON = TSDL_Keycode($0000003b); {*< ';' } + SDLK_LESS = TSDL_Keycode($0000003c); {*< '<' } + SDLK_EQUALS = TSDL_Keycode($0000003d); {*< '=' } + SDLK_GREATER = TSDL_Keycode($0000003e); {*< '>' } + SDLK_QUESTION = TSDL_Keycode($0000003f); {*< '?' } + SDLK_AT = TSDL_Keycode($00000040); {*< '@' } + SDLK_LEFTBRACKET = TSDL_Keycode($0000005b); {*< '[' } + SDLK_BACKSLASH = TSDL_Keycode($0000005c); {*< '\\' } + SDLK_RIGHTBRACKET = TSDL_Keycode($0000005d); {*< ']' } + SDLK_CARET = TSDL_Keycode($0000005e); {*< '^' } + SDLK_UNDERSCORE = TSDL_Keycode($0000005f); {*< '_' } + SDLK_GRAVE = TSDL_Keycode($00000060); {*< '`' } + SDLK_A = TSDL_Keycode($00000061); {*< 'a' } + SDLK_B = TSDL_Keycode($00000062); {*< 'b' } + SDLK_C = TSDL_Keycode($00000063); {*< 'c' } + SDLK_D = TSDL_Keycode($00000064); {*< 'd' } + SDLK_E = TSDL_Keycode($00000065); {*< 'e' } + SDLK_F = TSDL_Keycode($00000066); {*< 'f' } + SDLK_G = TSDL_Keycode($00000067); {*< 'g' } + SDLK_H = TSDL_Keycode($00000068); {*< 'h' } + SDLK_I = TSDL_Keycode($00000069); {*< 'i' } + SDLK_J = TSDL_Keycode($0000006a); {*< 'j' } + SDLK_K = TSDL_Keycode($0000006b); {*< 'k' } + SDLK_L = TSDL_Keycode($0000006c); {*< 'l' } + SDLK_M = TSDL_Keycode($0000006d); {*< 'm' } + SDLK_N = TSDL_Keycode($0000006e); {*< 'n' } + SDLK_O = TSDL_Keycode($0000006f); {*< 'o' } + SDLK_P = TSDL_Keycode($00000070); {*< 'p' } + SDLK_Q = TSDL_Keycode($00000071); {*< 'q' } + SDLK_R = TSDL_Keycode($00000072); {*< 'r' } + SDLK_S = TSDL_Keycode($00000073); {*< 's' } + SDLK_T = TSDL_Keycode($00000074); {*< 't' } + SDLK_U = TSDL_Keycode($00000075); {*< 'u' } + SDLK_V = TSDL_Keycode($00000076); {*< 'v' } + SDLK_W = TSDL_Keycode($00000077); {*< 'w' } + SDLK_X = TSDL_Keycode($00000078); {*< 'x' } + SDLK_Y = TSDL_Keycode($00000079); {*< 'y' } + SDLK_Z = TSDL_Keycode($0000007a); {*< 'z' } + SDLK_LEFTBRACE = TSDL_Keycode($0000007b); {*< '' } + SDLK_PIPE = TSDL_Keycode($0000007c); {*< '|' } + SDLK_RIGHTBRACE = TSDL_Keycode($0000007d); {*< '' } + SDLK_TILDE = TSDL_Keycode($0000007e); {*< '~' } + SDLK_DELETE = TSDL_Keycode($0000007f); {*< '\x7F' } + SDLK_PLUSMINUS = TSDL_Keycode($000000b1); {*< '\xB1' } + SDLK_CAPSLOCK = TSDL_Keycode($40000039); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CAPSLOCK) } + SDLK_F1 = TSDL_Keycode($4000003a); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F1) } + SDLK_F2 = TSDL_Keycode($4000003b); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F2) } + SDLK_F3 = TSDL_Keycode($4000003c); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F3) } + SDLK_F4 = TSDL_Keycode($4000003d); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F4) } + SDLK_F5 = TSDL_Keycode($4000003e); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F5) } + SDLK_F6 = TSDL_Keycode($4000003f); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F6) } + SDLK_F7 = TSDL_Keycode($40000040); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F7) } + SDLK_F8 = TSDL_Keycode($40000041); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F8) } + SDLK_F9 = TSDL_Keycode($40000042); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F9) } + SDLK_F10 = TSDL_Keycode($40000043); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F10) } + SDLK_F11 = TSDL_Keycode($40000044); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F11) } + SDLK_F12 = TSDL_Keycode($40000045); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F12) } + SDLK_PRINTSCREEN = TSDL_Keycode($40000046); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_PRINTSCREEN) } + SDLK_SCROLLLOCK = TSDL_Keycode($40000047); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_SCROLLLOCK) } + SDLK_PAUSE = TSDL_Keycode($40000048); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_PAUSE) } + SDLK_INSERT = TSDL_Keycode($40000049); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_INSERT) } + SDLK_HOME = TSDL_Keycode($4000004a); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_HOME) } + SDLK_PAGEUP = TSDL_Keycode($4000004b); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_PAGEUP) } + SDLK_END = TSDL_Keycode($4000004d); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_END) } + SDLK_PAGEDOWN = TSDL_Keycode($4000004e); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_PAGEDOWN) } + SDLK_RIGHT = TSDL_Keycode($4000004f); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_RIGHT) } + SDLK_LEFT = TSDL_Keycode($40000050); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_LEFT) } + SDLK_DOWN = TSDL_Keycode($40000051); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_DOWN) } + SDLK_UP = TSDL_Keycode($40000052); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_UP) } + SDLK_NUMLOCKCLEAR = TSDL_Keycode($40000053); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_NUMLOCKCLEAR) } + SDLK_KP_DIVIDE = TSDL_Keycode($40000054); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_DIVIDE) } + SDLK_KP_MULTIPLY = TSDL_Keycode($40000055); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MULTIPLY) } + SDLK_KP_MINUS = TSDL_Keycode($40000056); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MINUS) } + SDLK_KP_PLUS = TSDL_Keycode($40000057); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_PLUS) } + SDLK_KP_ENTER = TSDL_Keycode($40000058); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_ENTER) } + SDLK_KP_1 = TSDL_Keycode($40000059); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_1) } + SDLK_KP_2 = TSDL_Keycode($4000005a); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_2) } + SDLK_KP_3 = TSDL_Keycode($4000005b); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_3) } + SDLK_KP_4 = TSDL_Keycode($4000005c); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_4) } + SDLK_KP_5 = TSDL_Keycode($4000005d); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_5) } + SDLK_KP_6 = TSDL_Keycode($4000005e); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_6) } + SDLK_KP_7 = TSDL_Keycode($4000005f); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_7) } + SDLK_KP_8 = TSDL_Keycode($40000060); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_8) } + SDLK_KP_9 = TSDL_Keycode($40000061); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_9) } + SDLK_KP_0 = TSDL_Keycode($40000062); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_0) } + SDLK_KP_PERIOD = TSDL_Keycode($40000063); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_PERIOD) } + SDLK_APPLICATION = TSDL_Keycode($40000065); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_APPLICATION) } + SDLK_POWER = TSDL_Keycode($40000066); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_POWER) } + SDLK_KP_EQUALS = TSDL_Keycode($40000067); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_EQUALS) } + SDLK_F13 = TSDL_Keycode($40000068); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F13) } + SDLK_F14 = TSDL_Keycode($40000069); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F14) } + SDLK_F15 = TSDL_Keycode($4000006a); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F15) } + SDLK_F16 = TSDL_Keycode($4000006b); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F16) } + SDLK_F17 = TSDL_Keycode($4000006c); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F17) } + SDLK_F18 = TSDL_Keycode($4000006d); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F18) } + SDLK_F19 = TSDL_Keycode($4000006e); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F19) } + SDLK_F20 = TSDL_Keycode($4000006f); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F20) } + SDLK_F21 = TSDL_Keycode($40000070); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F21) } + SDLK_F22 = TSDL_Keycode($40000071); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F22) } + SDLK_F23 = TSDL_Keycode($40000072); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F23) } + SDLK_F24 = TSDL_Keycode($40000073); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F24) } + SDLK_EXECUTE = TSDL_Keycode($40000074); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_EXECUTE) } + SDLK_HELP = TSDL_Keycode($40000075); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_HELP) } + SDLK_MENU = TSDL_Keycode($40000076); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_MENU) } + SDLK_SELECT = TSDL_Keycode($40000077); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_SELECT) } + SDLK_STOP = TSDL_Keycode($40000078); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_STOP) } + SDLK_AGAIN = TSDL_Keycode($40000079); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AGAIN) } + SDLK_UNDO = TSDL_Keycode($4000007a); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_UNDO) } + SDLK_CUT = TSDL_Keycode($4000007b); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CUT) } + SDLK_COPY = TSDL_Keycode($4000007c); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_COPY) } + SDLK_PASTE = TSDL_Keycode($4000007d); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_PASTE) } + SDLK_FIND = TSDL_Keycode($4000007e); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_FIND) } + SDLK_MUTE = TSDL_Keycode($4000007f); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_MUTE) } + SDLK_VOLUMEUP = TSDL_Keycode($40000080); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_VOLUMEUP) } + SDLK_VOLUMEDOWN = TSDL_Keycode($40000081); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_VOLUMEDOWN) } + SDLK_KP_COMMA = TSDL_Keycode($40000085); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_COMMA) } + SDLK_KP_EQUALSAS400 = TSDL_Keycode($40000086); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_EQUALSAS400) } + SDLK_ALTERASE = TSDL_Keycode($40000099); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_ALTERASE) } + SDLK_SYSREQ = TSDL_Keycode($4000009a); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_SYSREQ) } + SDLK_CANCEL = TSDL_Keycode($4000009b); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CANCEL) } + SDLK_CLEAR = TSDL_Keycode($4000009c); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CLEAR) } + SDLK_PRIOR = TSDL_Keycode($4000009d); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_PRIOR) } + SDLK_RETURN2 = TSDL_Keycode($4000009e); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_RETURN2) } + SDLK_SEPARATOR = TSDL_Keycode($4000009f); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_SEPARATOR) } + SDLK_OUT = TSDL_Keycode($400000a0); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_OUT) } + SDLK_OPER = TSDL_Keycode($400000a1); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_OPER) } + SDLK_CLEARAGAIN = TSDL_Keycode($400000a2); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CLEARAGAIN) } + SDLK_CRSEL = TSDL_Keycode($400000a3); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CRSEL) } + SDLK_EXSEL = TSDL_Keycode($400000a4); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_EXSEL) } + SDLK_KP_00 = TSDL_Keycode($400000b0); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_00) } + SDLK_KP_000 = TSDL_Keycode($400000b1); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_000) } + SDLK_THOUSANDSSEPARATOR = TSDL_Keycode($400000b2); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_THOUSANDSSEPARATOR) } + SDLK_DECIMALSEPARATOR = TSDL_Keycode($400000b3); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_DECIMALSEPARATOR) } + SDLK_CURRENCYUNIT = TSDL_Keycode($400000b4); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CURRENCYUNIT) } + SDLK_CURRENCYSUBUNIT = TSDL_Keycode($400000b5); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CURRENCYSUBUNIT) } + SDLK_KP_LEFTPAREN = TSDL_Keycode($400000b6); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_LEFTPAREN) } + SDLK_KP_RIGHTPAREN = TSDL_Keycode($400000b7); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_RIGHTPAREN) } + SDLK_KP_LEFTBRACE = TSDL_Keycode($400000b8); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_LEFTBRACE) } + SDLK_KP_RIGHTBRACE = TSDL_Keycode($400000b9); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_RIGHTBRACE) } + SDLK_KP_TAB = TSDL_Keycode($400000ba); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_TAB) } + SDLK_KP_BACKSPACE = TSDL_Keycode($400000bb); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_BACKSPACE) } + SDLK_KP_A = TSDL_Keycode($400000bc); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_A) } + SDLK_KP_B = TSDL_Keycode($400000bd); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_B) } + SDLK_KP_C = TSDL_Keycode($400000be); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_C) } + SDLK_KP_D = TSDL_Keycode($400000bf); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_D) } + SDLK_KP_E = TSDL_Keycode($400000c0); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_E) } + SDLK_KP_F = TSDL_Keycode($400000c1); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_F) } + SDLK_KP_XOR = TSDL_Keycode($400000c2); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_XOR) } + SDLK_KP_POWER = TSDL_Keycode($400000c3); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_POWER) } + SDLK_KP_PERCENT = TSDL_Keycode($400000c4); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_PERCENT) } + SDLK_KP_LESS = TSDL_Keycode($400000c5); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_LESS) } + SDLK_KP_GREATER = TSDL_Keycode($400000c6); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_GREATER) } + SDLK_KP_AMPERSAND = TSDL_Keycode($400000c7); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_AMPERSAND) } + SDLK_KP_DBLAMPERSAND = TSDL_Keycode($400000c8); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_DBLAMPERSAND) } + SDLK_KP_VERTICALBAR = TSDL_Keycode($400000c9); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_VERTICALBAR) } + SDLK_KP_DBLVERTICALBAR = TSDL_Keycode($400000ca); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_DBLVERTICALBAR) } + SDLK_KP_COLON = TSDL_Keycode($400000cb); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_COLON) } + SDLK_KP_HASH = TSDL_Keycode($400000cc); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_HASH) } + SDLK_KP_SPACE = TSDL_Keycode($400000cd); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_SPACE) } + SDLK_KP_AT = TSDL_Keycode($400000ce); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_AT) } + SDLK_KP_EXCLAM = TSDL_Keycode($400000cf); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_EXCLAM) } + SDLK_KP_MEMSTORE = TSDL_Keycode($400000d0); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMSTORE) } + SDLK_KP_MEMRECALL = TSDL_Keycode($400000d1); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMRECALL) } + SDLK_KP_MEMCLEAR = TSDL_Keycode($400000d2); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMCLEAR) } + SDLK_KP_MEMADD = TSDL_Keycode($400000d3); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMADD) } + SDLK_KP_MEMSUBTRACT = TSDL_Keycode($400000d4); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMSUBTRACT) } + SDLK_KP_MEMMULTIPLY = TSDL_Keycode($400000d5); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMMULTIPLY) } + SDLK_KP_MEMDIVIDE = TSDL_Keycode($400000d6); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMDIVIDE) } + SDLK_KP_PLUSMINUS = TSDL_Keycode($400000d7); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_PLUSMINUS) } + SDLK_KP_CLEAR = TSDL_Keycode($400000d8); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_CLEAR) } + SDLK_KP_CLEARENTRY = TSDL_Keycode($400000d9); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_CLEARENTRY) } + SDLK_KP_BINARY = TSDL_Keycode($400000da); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_BINARY) } + SDLK_KP_OCTAL = TSDL_Keycode($400000db); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_OCTAL) } + SDLK_KP_DECIMAL = TSDL_Keycode($400000dc); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_DECIMAL) } + SDLK_KP_HEXADECIMAL = TSDL_Keycode($400000dd); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_HEXADECIMAL) } + SDLK_LCTRL = TSDL_Keycode($400000e0); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_LCTRL) } + SDLK_LSHIFT = TSDL_Keycode($400000e1); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_LSHIFT) } + SDLK_LALT = TSDL_Keycode($400000e2); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_LALT) } + SDLK_LGUI = TSDL_Keycode($400000e3); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_LGUI) } + SDLK_RCTRL = TSDL_Keycode($400000e4); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_RCTRL) } + SDLK_RSHIFT = TSDL_Keycode($400000e5); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_RSHIFT) } + SDLK_RALT = TSDL_Keycode($400000e6); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_RALT) } + SDLK_RGUI = TSDL_Keycode($400000e7); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_RGUI) } + SDLK_MODE = TSDL_Keycode($40000101); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_MODE) } + SDLK_SLEEP = TSDL_Keycode($40000102); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_SLEEP) } + SDLK_WAKE = TSDL_Keycode($40000103); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_WAKE) } + SDLK_CHANNEL_INCREMENT = TSDL_Keycode($40000104); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CHANNEL_INCREMENT) } + SDLK_CHANNEL_DECREMENT = TSDL_Keycode($40000105); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CHANNEL_DECREMENT) } + SDLK_MEDIA_PLAY = TSDL_Keycode($40000106); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_MEDIA_PLAY) } + SDLK_MEDIA_PAUSE = TSDL_Keycode($40000107); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_MEDIA_PAUSE) } + SDLK_MEDIA_RECORD = TSDL_Keycode($40000108); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_MEDIA_RECORD) } + SDLK_MEDIA_FAST_FORWARD = TSDL_Keycode($40000109); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_MEDIA_FAST_FORWARD) } + SDLK_MEDIA_REWIND = TSDL_Keycode($4000010a); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_MEDIA_REWIND) } + SDLK_MEDIA_NEXT_TRACK = TSDL_Keycode($4000010b); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_MEDIA_NEXT_TRACK) } + SDLK_MEDIA_PREVIOUS_TRACK = TSDL_Keycode($4000010c); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_MEDIA_PREVIOUS_TRACK) } + SDLK_MEDIA_STOP = TSDL_Keycode($4000010d); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_MEDIA_STOP) } + SDLK_MEDIA_EJECT = TSDL_Keycode($4000010e); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_MEDIA_EJECT) } + SDLK_MEDIA_PLAY_PAUSE = TSDL_Keycode($4000010f); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_MEDIA_PLAY_PAUSE) } + SDLK_MEDIA_SELECT = TSDL_Keycode($40000110); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_MEDIA_SELECT) } + SDLK_AC_NEW = TSDL_Keycode($40000111); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_NEW) } + SDLK_AC_OPEN = TSDL_Keycode($40000112); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_OPEN) } + SDLK_AC_CLOSE = TSDL_Keycode($40000113); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_CLOSE) } + SDLK_AC_EXIT = TSDL_Keycode($40000114); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_EXIT) } + SDLK_AC_SAVE = TSDL_Keycode($40000115); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_SAVE) } + SDLK_AC_PRINT = TSDL_Keycode($40000116); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_PRINT) } + SDLK_AC_PROPERTIES = TSDL_Keycode($40000117); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_PROPERTIES) } + SDLK_AC_SEARCH = TSDL_Keycode($40000118); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_SEARCH) } + SDLK_AC_HOME = TSDL_Keycode($40000119); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_HOME) } + SDLK_AC_BACK = TSDL_Keycode($4000011a); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_BACK) } + SDLK_AC_FORWARD = TSDL_Keycode($4000011b); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_FORWARD) } + SDLK_AC_STOP = TSDL_Keycode($4000011c); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_STOP) } + SDLK_AC_REFRESH = TSDL_Keycode($4000011d); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_REFRESH) } + SDLK_AC_BOOKMARKS = TSDL_Keycode($4000011e); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_BOOKMARKS) } + SDLK_SOFTLEFT = TSDL_Keycode($4000011f); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_SOFTLEFT) } + SDLK_SOFTRIGHT = TSDL_Keycode($40000120); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_SOFTRIGHT) } + SDLK_CALL = TSDL_Keycode($40000121); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CALL) } + SDLK_ENDCALL = TSDL_Keycode($40000122); {*< SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_ENDCALL) } + +{* + * Valid key modifiers (possibly OR'd together). + * + * \since This datatype is available since SDL 3.1.3. + } +type + PPSDL_Keymod = ^PSDL_Keymod; + PSDL_Keymod = ^TSDL_Keymod; + TSDL_Keymod = type cuint16; + +const + SDL_KMOD_NONE = TSDL_Keymod($0000); {*< no modifier is applicable. } + SDL_KMOD_LSHIFT = TSDL_Keymod($0001); {*< the left Shift key is down. } + SDL_KMOD_RSHIFT = TSDL_Keymod($0002); {*< the right Shift key is down. } + SDL_KMOD_LCTRL = TSDL_Keymod($0040); {*< the left Ctrl (Control) key is down. } + SDL_KMOD_RCTRL = TSDL_Keymod($0080); {*< the right Ctrl (Control) key is down. } + SDL_KMOD_LALT = TSDL_Keymod($0100); {*< the left Alt key is down. } + SDL_KMOD_RALT = TSDL_Keymod($0200); {*< the right Alt key is down. } + SDL_KMOD_LGUI = TSDL_Keymod($0400); {*< the left GUI key (often the Windows key) is down. } + SDL_KMOD_RGUI = TSDL_Keymod($0800); {*< the right GUI key (often the Windows key) is down. } + SDL_KMOD_NUM = TSDL_Keymod($1000); {*< the Num Lock key (may be located on an extended keypad) is down. } + SDL_KMOD_CAPS = TSDL_Keymod($2000); {*< the Caps Lock key is down. } + SDL_KMOD_MODE = TSDL_Keymod($4000); {*< the !AltGr key is down. } + SDL_KMOD_SCROLL = TSDL_Keymod($8000); {*< the Scroll Lock key is down. } + SDL_KMOD_CTRL = TSDL_Keymod(SDL_KMOD_LCTRL or SDL_KMOD_RCTRL); {*< Any Ctrl key is down. } + SDL_KMOD_SHIFT = TSDL_Keymod(SDL_KMOD_LSHIFT or SDL_KMOD_RSHIFT); {*< Any Shift key is down. } + SDL_KMOD_ALT = TSDL_Keymod(SDL_KMOD_LALT or SDL_KMOD_RALT); {*< Any Alt key is down. } + SDL_KMOD_GUI = TSDL_Keymod(SDL_KMOD_LGUI or SDL_KMOD_RGUI); {*< Any GUI key is down. } + diff --git a/units/SDL_mouse.inc b/units/SDL_mouse.inc new file mode 100644 index 0000000..dcbe2ad --- /dev/null +++ b/units/SDL_mouse.inc @@ -0,0 +1,578 @@ +{ + This file is part of: + + SDL3 for Pascal + (https://github.com/PascalGameDevelopment/SDL3-for-Pascal) + SPDX-License-Identifier: Zlib +} + +{* + * # CategoryMouse + * + * SDL mouse handling. + } + +{* + * This is a unique ID for a mouse for the time it is connected to the system, + * and is never reused for the lifetime of the application. + * + * If the mouse is disconnected and reconnected, it will get a new ID. + * + * The value 0 is an invalid ID. + * + * \since This datatype is available since SDL 3.1.3. + } +type + PPSDL_MouseID = ^PSDL_MouseID; + PSDL_MouseID = ^TSDL_MouseID; + TSDL_MouseID = cuint32; + +{* + * The structure used to identify an SDL cursor. + * + * This is opaque data. + * + * \since This struct is available since SDL 3.1.3. + } +type + PPSDL_Cursor = ^PSDL_Cursor; + PSDL_Cursor = type Pointer; + +{* + * Cursor types for SDL_CreateSystemCursor(). + * + * \since This enum is available since SDL 3.1.3. + } +type + PPSDL_SystemCursor = ^PSDL_SystemCursor; + PSDL_SystemCursor = ^TSDL_SystemCursor; + TSDL_SystemCursor = type Integer; +const + SDL_SYSTEM_CURSOR_DEFAULT = TSDL_SystemCursor(0); {*< Default cursor. Usually an arrow. } + SDL_SYSTEM_CURSOR_TEXT = TSDL_SystemCursor(1); {*< Text selection. Usually an I-beam. } + SDL_SYSTEM_CURSOR_WAIT = TSDL_SystemCursor(2); {*< Wait. Usually an hourglass or watch or spinning ball. } + SDL_SYSTEM_CURSOR_CROSSHAIR = TSDL_SystemCursor(3); {*< Crosshair. } + SDL_SYSTEM_CURSOR_PROGRESS = TSDL_SystemCursor(4); {*< Program is busy but still interactive. Usually it's WAIT with an arrow. } + SDL_SYSTEM_CURSOR_NWSE_RESIZE = TSDL_SystemCursor(5); {*< Double arrow pointing northwest and southeast. } + SDL_SYSTEM_CURSOR_NESW_RESIZE = TSDL_SystemCursor(6); {*< Double arrow pointing northeast and southwest. } + SDL_SYSTEM_CURSOR_EW_RESIZE = TSDL_SystemCursor(7); {*< Double arrow pointing west and east. } + SDL_SYSTEM_CURSOR_NS_RESIZE = TSDL_SystemCursor(8); {*< Double arrow pointing north and south. } + SDL_SYSTEM_CURSOR_MOVE = TSDL_SystemCursor(9); {*< Four pointed arrow pointing north, south, east, and west. } + SDL_SYSTEM_CURSOR_NOT_ALLOWED = TSDL_SystemCursor(10); {*< Not permitted. Usually a slashed circle or crossbones. } + SDL_SYSTEM_CURSOR_POINTER = TSDL_SystemCursor(11); {*< Pointer that indicates a link. Usually a pointing hand. } + SDL_SYSTEM_CURSOR_NW_RESIZE = TSDL_SystemCursor(12); {*< Window resize top-left. This may be a single arrow or a double arrow like NWSE_RESIZE. } + SDL_SYSTEM_CURSOR_N_RESIZE = TSDL_SystemCursor(13); {*< Window resize top. May be NS_RESIZE. } + SDL_SYSTEM_CURSOR_NE_RESIZE = TSDL_SystemCursor(14); {*< Window resize top-right. May be NESW_RESIZE. } + SDL_SYSTEM_CURSOR_E_RESIZE = TSDL_SystemCursor(15); {*< Window resize right. May be EW_RESIZE. } + SDL_SYSTEM_CURSOR_SE_RESIZE = TSDL_SystemCursor(16); {*< Window resize bottom-right. May be NWSE_RESIZE. } + SDL_SYSTEM_CURSOR_S_RESIZE = TSDL_SystemCursor(17); {*< Window resize bottom. May be NS_RESIZE. } + SDL_SYSTEM_CURSOR_SW_RESIZE = TSDL_SystemCursor(18); {*< Window resize bottom-left. May be NESW_RESIZE. } + SDL_SYSTEM_CURSOR_W_RESIZE = TSDL_SystemCursor(19); {*< Window resize left. May be EW_RESIZE. } + SDL_SYSTEM_CURSOR_COUNT = TSDL_SystemCursor(20); + +{* + * Scroll direction types for the Scroll event + * + * \since This enum is available since SDL 3.1.3. + } +type + PPSDL_MouseWheelDirection = ^PSDL_MouseWheelDirection; + PSDL_MouseWheelDirection = ^TSDL_MouseWheelDirection; + TSDL_MouseWheelDirection = Integer; +const + SDL_MOUSEWHEEL_NORMAL = TSDL_MouseWheelDirection(0); {*< The scroll direction is normal } + SDL_MOUSEWHEEL_FLIPPED = TSDL_MouseWheelDirection(1); {*< The scroll direction is flipped / natural } + +{* + * A bitmask of pressed mouse buttons, as reported by SDL_GetMouseState, etc. + * + * - Button 1: Left mouse button + * - Button 2: Middle mouse button + * - Button 3: Right mouse button + * - Button 4: Side mouse button 1 + * - Button 5: Side mouse button 2 + * + * \since This datatype is available since SDL 3.1.3. + * + * \sa SDL_GetMouseState + * \sa SDL_GetGlobalMouseState + * \sa SDL_GetRelativeMouseState + } +type + PPSDL_MouseButtonFlags = ^PSDL_MouseButtonFlags; + PSDL_MouseButtonFlags = ^TSDL_MouseButtonFlags; + TSDL_MouseButtonFlags = type cuint32; + +const + SDL_BUTTON_LEFT = TSDL_MouseButtonFlags(1); + SDL_BUTTON_MIDDLE = TSDL_MouseButtonFlags(2); + SDL_BUTTON_RIGHT = TSDL_MouseButtonFlags(3); + SDL_BUTTON_X1 = TSDL_MouseButtonFlags(4); + SDL_BUTTON_X2 = TSDL_MouseButtonFlags(5); + + {SDL3-for-Pascal: The C macro SDL_BUTTON_MASK is not implemented but the mask + defines are directly translated. } + {#define SDL_BUTTON_MASK(X) (1u << ((X)-1)) } + SDL_BUTTON_LMASK = TSDL_MouseButtonFlags(1 shl SDL_BUTTON_LEFT-1); { SDL_BUTTON_MASK(SDL_BUTTON_LEFT) } + SDL_BUTTON_MMASK = TSDL_MouseButtonFlags(1 shl SDL_BUTTON_MIDDLE-1); { SDL_BUTTON_MASK(SDL_BUTTON_MIDDLE) } + SDL_BUTTON_RMASK = TSDL_MouseButtonFlags(1 shl SDL_BUTTON_RIGHT-1); { SDL_BUTTON_MASK(SDL_BUTTON_RIGHT) } + SDL_BUTTON_X1MASK = TSDL_MouseButtonFlags(1 shl SDL_BUTTON_X1-1); { SDL_BUTTON_MASK(SDL_BUTTON_X1) } + SDL_BUTTON_X2MASK = TSDL_MouseButtonFlags(1 shl SDL_BUTTON_X2-1); { SDL_BUTTON_MASK(SDL_BUTTON_X2) } + +{ Function prototypes } + +{* + * Return whether a mouse is currently connected. + * + * \returns true if a mouse is connected, false otherwise. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetMice + } +function SDL_HasMouse: cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HasMouse' {$ENDIF} {$ENDIF}; + +{* + * Get a list of currently connected mice. + * + * Note that this will include any device or virtual driver that includes + * mouse functionality, including some game controllers, KVM switches, etc. + * You should wait for input from a device before you consider it actively in + * use. + * + * \param count a Pointer filled in with the number of mice returned, may be + * nil. + * \returns a 0 terminated array of mouse instance IDs or nil on failure; + * call SDL_GetError() for more information. This should be freed + * with SDL_free() when it is no longer needed. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetMouseNameForID + * \sa SDL_HasMouse + } +function SDL_GetMice(count: pcint): PSDL_MouseID; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetMice' {$ENDIF} {$ENDIF}; + +{* + * Get the name of a mouse. + * + * This function returns "" if the mouse doesn't have a name. + * + * \param instance_id the mouse instance ID. + * \returns the name of the selected mouse, or nil on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetMice + } +function SDL_GetMouseNameForID(instance_id: TSDL_MouseID): PAnsiChar; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetMouseNameForID' {$ENDIF} {$ENDIF}; + +{* + * Get the window which currently has mouse focus. + * + * \returns the window with mouse focus. + * + * \since This function is available since SDL 3.1.3. + } +function SDL_GetMouseFocus: PSDL_Window; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetMouseFocus' {$ENDIF} {$ENDIF}; + +{* + * Retrieve the current state of the mouse. + * + * The current button state is returned as a button bitmask, which can be + * tested using the SDL_BUTTON_MASK(X) macro (where `X` is generally 1 for the + * left, 2 for middle, 3 for the right button), and `x` and `y` are set to the + * mouse cursor position relative to the focus window. You can pass nil for + * either `x` or `y`. + * + * \param x the x coordinate of the mouse cursor position relative to the + * focus window. + * \param y the y coordinate of the mouse cursor position relative to the + * focus window. + * \returns a 32-bit button bitmask of the current button state. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetGlobalMouseState + * \sa SDL_GetRelativeMouseState + } +function SDL_GetMouseState(x: pcfloat; y: pcfloat): TSDL_MouseButtonFlags; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetMouseState' {$ENDIF} {$ENDIF}; + +{* + * Get the current state of the mouse in relation to the desktop. + * + * This works similarly to SDL_GetMouseState(), but the coordinates will be + * reported relative to the top-left of the desktop. This can be useful if you + * need to track the mouse outside of a specific window and SDL_CaptureMouse() + * doesn't fit your needs. For example, it could be useful if you need to + * track the mouse while dragging a window, where coordinates relative to a + * window might not be in sync at all times. + * + * Note: SDL_GetMouseState() returns the mouse position as SDL understands it + * from the last pump of the event queue. This function, however, queries the + * OS for the current mouse position, and as such, might be a slightly less + * efficient function. Unless you know what you're doing and have a good + * reason to use this function, you probably want SDL_GetMouseState() instead. + * + * \param x filled in with the current X coord relative to the desktop; can be + * nil. + * \param y filled in with the current Y coord relative to the desktop; can be + * nil. + * \returns the current button state as a bitmask which can be tested using + * the SDL_BUTTON_MASK(X) macros. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_CaptureMouse + * \sa SDL_GetMouseState + } +function SDL_GetGlobalMouseState(x: pcfloat; y: pcfloat): TSDL_MouseButtonFlags; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetGlobalMouseState' {$ENDIF} {$ENDIF}; + +{* + * Retrieve the relative state of the mouse. + * + * The current button state is returned as a button bitmask, which can be + * tested using the `SDL_BUTTON_MASK(X)` macros (where `X` is generally 1 for + * the left, 2 for middle, 3 for the right button), and `x` and `y` are set to + * the mouse deltas since the last call to SDL_GetRelativeMouseState() or + * since event initialization. You can pass nil for either `x` or `y`. + * + * \param x a Pointer filled with the last recorded x coordinate of the mouse. + * \param y a Pointer filled with the last recorded y coordinate of the mouse. + * \returns a 32-bit button bitmask of the relative button state. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetMouseState + } +function SDL_GetRelativeMouseState(x: pcfloat; y: pcfloat): TSDL_MouseButtonFlags; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetRelativeMouseState' {$ENDIF} {$ENDIF}; + +{* + * Move the mouse cursor to the given position within the window. + * + * This function generates a mouse motion event if relative mode is not + * enabled. If relative mode is enabled, you can force mouse events for the + * warp by setting the SDL_HINT_MOUSE_RELATIVE_WARP_MOTION hint. + * + * Note that this function will appear to succeed, but not actually move the + * mouse when used over Microsoft Remote Desktop. + * + * \param window the window to move the mouse into, or nil for the current + * mouse focus. + * \param x the x coordinate within the window. + * \param y the y coordinate within the window. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_WarpMouseGlobal + } +procedure SDL_WarpMouseInWindow(window: PSDL_Window; x: cfloat; y: cfloat); cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_WarpMouseInWindow' {$ENDIF} {$ENDIF}; + +{* + * Move the mouse to the given position in global screen space. + * + * This function generates a mouse motion event. + * + * A failure of this function usually means that it is unsupported by a + * platform. + * + * Note that this function will appear to succeed, but not actually move the + * mouse when used over Microsoft Remote Desktop. + * + * \param x the x coordinate. + * \param y the y coordinate. + * \returns true on success or false on failure; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_WarpMouseInWindow + } +function SDL_WarpMouseGlobal(x: cfloat; y: cfloat): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_WarpMouseGlobal' {$ENDIF} {$ENDIF}; + +{* + * Set relative mouse mode for a window. + * + * While the window has focus and relative mouse mode is enabled, the cursor + * is hidden, the mouse position is constrained to the window, and SDL will + * report continuous relative mouse motion even if the mouse is at the edge of + * the window. + * + * This function will flush any pending mouse motion for this window. + * + * \param window the window to change. + * \param enabled true to enable relative mode, false to disable. + * \returns true on success or false on failure; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetWindowRelativeMouseMode + } +function SDL_SetWindowRelativeMouseMode(window: PSDL_Window; enabled: cbool): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetWindowRelativeMouseMode' {$ENDIF} {$ENDIF}; + +{* + * Query whether relative mouse mode is enabled for a window. + * + * \param window the window to query. + * \returns true if relative mode is enabled for a window or false otherwise. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_SetWindowRelativeMouseMode + } +function SDL_GetWindowRelativeMouseMode(window: PSDL_Window): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetWindowRelativeMouseMode' {$ENDIF} {$ENDIF}; + +{* + * Capture the mouse and to track input outside an SDL window. + * + * Capturing enables your app to obtain mouse events globally, instead of just + * within your window. Not all video targets support this function. When + * capturing is enabled, the current window will get all mouse events, but + * unlike relative mode, no change is made to the cursor and it is not + * restrained to your window. + * + * This function may also deny mouse input to other windows--both those in + * your application and others on the system--so you should use this function + * sparingly, and in small bursts. For example, you might want to track the + * mouse while the user is dragging something, until the user releases a mouse + * button. It is not recommended that you capture the mouse for long periods + * of time, such as the entire time your app is running. For that, you should + * probably use SDL_SetWindowRelativeMouseMode() or SDL_SetWindowMouseGrab(), + * depending on your goals. + * + * While captured, mouse events still report coordinates relative to the + * current (foreground) window, but those coordinates may be outside the + * bounds of the window (including negative values). Capturing is only allowed + * for the foreground window. If the window loses focus while capturing, the + * capture will be disabled automatically. + * + * While capturing is enabled, the current window will have the + * `SDL_WINDOW_MOUSE_CAPTURE` flag set. + * + * Please note that SDL will attempt to "auto capture" the mouse while the + * user is pressing a button; this is to try and make mouse behavior more + * consistent between platforms, and deal with the common case of a user + * dragging the mouse outside of the window. This means that if you are + * calling SDL_CaptureMouse() only to deal with this situation, you do not + * have to (although it is safe to do so). If this causes problems for your + * app, you can disable auto capture by setting the + * `SDL_HINT_MOUSE_AUTO_CAPTURE` hint to zero. + * + * \param enabled true to enable capturing, false to disable. + * \returns true on success or false on failure; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetGlobalMouseState + } +function SDL_CaptureMouse(enabled: cbool): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_CaptureMouse' {$ENDIF} {$ENDIF}; + +{* + * Create a cursor using the specified bitmap data and mask (in MSB format). + * + * `mask` has to be in MSB (Most Significant Bit) format. + * + * The cursor width (`w`) must be a multiple of 8 bits. + * + * The cursor is created in black and white according to the following: + * + * - data=0, mask=1: white + * - data=1, mask=1: black + * - data=0, mask=0: transparent + * - data=1, mask=0: inverted color if possible, black if not. + * + * Cursors created with this function must be freed with SDL_DestroyCursor(). + * + * If you want to have a color cursor, or create your cursor from an + * SDL_Surface, you should use SDL_CreateColorCursor(). Alternately, you can + * hide the cursor and draw your own as part of your game's rendering, but it + * will be bound to the framerate. + * + * Also, SDL_CreateSystemCursor() is available, which provides several + * readily-available system cursors to pick from. + * + * \param data the color value for each pixel of the cursor. + * \param mask the mask value for each pixel of the cursor. + * \param w the width of the cursor. + * \param h the height of the cursor. + * \param hot_x the x-axis offset from the left of the cursor image to the + * mouse x position, in the range of 0 to `w` - 1. + * \param hot_y the y-axis offset from the top of the cursor image to the + * mouse y position, in the range of 0 to `h` - 1. + * \returns a new cursor with the specified parameters on success or nil on + * failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_CreateColorCursor + * \sa SDL_CreateSystemCursor + * \sa SDL_DestroyCursor + * \sa SDL_SetCursor + } +function SDL_CreateCursor(data: pcuint8; mask: pcuint8; w: cint; h: cint; hot_x: cint; hot_y: cint): PSDL_Cursor; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_CreateCursor' {$ENDIF} {$ENDIF}; + +{* + * Create a color cursor. + * + * If this function is passed a surface with alternate representations, the + * surface will be interpreted as the content to be used for 100% display + * scale, and the alternate representations will be used for high DPI + * situations. For example, if the original surface is 32x32, then on a 2x + * macOS display or 200% display scale on Windows, a 64x64 version of the + * image will be used, if available. If a matching version of the image isn't + * available, the closest larger size image will be downscaled to the + * appropriate size and be used instead, if available. Otherwise, the closest + * smaller image will be upscaled and be used instead. + * + * \param surface an SDL_Surface structure representing the cursor image. + * \param hot_x the x position of the cursor hot spot. + * \param hot_y the y position of the cursor hot spot. + * \returns the new cursor on success or nil on failure; call SDL_GetError() + * for more information. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_CreateCursor + * \sa SDL_CreateSystemCursor + * \sa SDL_DestroyCursor + * \sa SDL_SetCursor + } +function SDL_CreateColorCursor(surface: PSDL_Surface; hot_x: cint; hot_y: cint): PSDL_Cursor; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_CreateColorCursor' {$ENDIF} {$ENDIF}; + +{* + * Create a system cursor. + * + * \param id an SDL_SystemCursor enum value. + * \returns a cursor on success or nil on failure; call SDL_GetError() for + * more information. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_DestroyCursor + } +function SDL_CreateSystemCursor(id: TSDL_SystemCursor): PSDL_Cursor; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_CreateSystemCursor' {$ENDIF} {$ENDIF}; + +{* + * Set the active cursor. + * + * This function sets the currently active cursor to the specified one. If the + * cursor is currently visible, the change will be immediately represented on + * the display. SDL_SetCursor(nil) can be used to force cursor redraw, if + * this is desired for any reason. + * + * \param cursor a cursor to make active. + * \returns true on success or false on failure; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_GetCursor + } +function SDL_SetCursor(cursor: PSDL_Cursor): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_SetCursor' {$ENDIF} {$ENDIF}; + +{* + * Get the active cursor. + * + * This function returns a Pointer to the current cursor which is owned by the + * library. It is not necessary to free the cursor with SDL_DestroyCursor(). + * + * \returns the active cursor or nil if there is no mouse. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_SetCursor + } +function SDL_GetCursor: PSDL_Cursor; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetCursor' {$ENDIF} {$ENDIF}; + +{* + * Get the default cursor. + * + * You do not have to call SDL_DestroyCursor() on the return value, but it is + * safe to do so. + * + * \returns the default cursor on success or nil on failuree; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 3.1.3. + } +function SDL_GetDefaultCursor: PSDL_Cursor; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetDefaultCursor' {$ENDIF} {$ENDIF}; + +{* + * Free a previously-created cursor. + * + * Use this function to free cursor resources created with SDL_CreateCursor(), + * SDL_CreateColorCursor() or SDL_CreateSystemCursor(). + * + * \param cursor the cursor to free. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_CreateColorCursor + * \sa SDL_CreateCursor + * \sa SDL_CreateSystemCursor + } +procedure SDL_DestroyCursor(cursor: PSDL_Cursor); cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_DestroyCursor' {$ENDIF} {$ENDIF}; + +{* + * Show the cursor. + * + * \returns true on success or false on failure; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_CursorVisible + * \sa SDL_HideCursor + } +function SDL_ShowCursor: cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_ShowCursor' {$ENDIF} {$ENDIF}; + +{* + * Hide the cursor. + * + * \returns true on success or false on failure; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_CursorVisible + * \sa SDL_ShowCursor + } +function SDL_HideCursor: cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_HideCursor' {$ENDIF} {$ENDIF}; + +{* + * Return whether the cursor is currently being shown. + * + * \returns `true` if the cursor is being shown, or `false` if the cursor is + * hidden. + * + * \since This function is available since SDL 3.1.3. + * + * \sa SDL_HideCursor + * \sa SDL_ShowCursor + } +function SDL_CursorVisible: cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_CursorVisible' {$ENDIF} {$ENDIF}; diff --git a/units/SDL_pen.inc b/units/SDL_pen.inc new file mode 100644 index 0000000..e8f8401 --- /dev/null +++ b/units/SDL_pen.inc @@ -0,0 +1,88 @@ +{ + This file is part of: + + SDL3 for Pascal + (https://github.com/PascalGameDevelopment/SDL3-for-Pascal) + SPDX-License-Identifier: Zlib +} + +{* + * # CategoryPen + * + * SDL pen event handling. + * + * SDL provides an API for pressure-sensitive pen (stylus and/or eraser) + * handling, e.g., for input and drawing tablets or suitably equipped mobile / + * tablet devices. + * + * To get started with pens, simply handle SDL_EVENT_PEN_* events. When a pen + * starts providing input, SDL will assign it a unique SDL_PenID, which will + * remain for the life of the process, as long as the pen stays connected. + * + * Pens may provide more than simple touch input; they might have other axes, + * such as pressure, tilt, rotation, etc. + } + +{* + * SDL pen instance IDs. + * + * Zero is used to signify an invalid/null device. + * + * These show up in pen events when SDL sees input from them. They remain + * consistent as long as SDL can recognize a tool to be the same pen; but if a + * pen physically leaves the area and returns, it might get a new ID. + * + * \since This datatype is available since SDL 3.1.3. + } +type + PPSDL_PenID = ^PSDL_PenID; + PSDL_PenID = ^TSDL_PenID; + TSDL_PenID = cuint32; + +{* + * Pen input flags, as reported by various pen events' `pen_state` field. + * + * \since This datatype is available since SDL 3.1.3. + } + PPSDL_PenInputFlags = ^PSDL_PenInputFlags; + PSDL_PenInputFlags = ^TSDL_PenInputFlags; + TSDL_PenInputFlags = cuint32; + +const + SDL_PEN_INPUT_DOWN = TSDL_PenInputFlags(1 shl 0); {*< pen is pressed down } + SDL_PEN_INPUT_BUTTON_1 = TSDL_PenInputFlags(1 shl 1); {*< button 1 is pressed } + SDL_PEN_INPUT_BUTTON_2 = TSDL_PenInputFlags(1 shl 2); {*< button 2 is pressed } + SDL_PEN_INPUT_BUTTON_3 = TSDL_PenInputFlags(1 shl 3); {*< button 3 is pressed } + SDL_PEN_INPUT_BUTTON_4 = TSDL_PenInputFlags(1 shl 4); {*< button 4 is pressed } + SDL_PEN_INPUT_BUTTON_5 = TSDL_PenInputFlags(1 shl 5); {*< button 5 is pressed } + SDL_PEN_INPUT_ERASER_TIP = TSDL_PenInputFlags(1 shl 30); {*< eraser tip is used } + + {* + * Pen axis indices. + * + * These are the valid values for the `axis` field in SDL_PenAxisEvent. All + * axes are either normalised to 0..1 or report a (positive or negative) angle + * in degrees, with 0.0 representing the centre. Not all pens/backends support + * all axes: unsupported axes are always zero. + * + * To convert angles for tilt and rotation into vector representation, use + * SDL_sinf on the XTILT, YTILT, or ROTATION component, for example: + * + * `SDL_sinf(xtilt * SDL_PI_F / 180.0)`. + * + * \since This enum is available since SDL 3.1.3 + } +type + PPSDL_PenAxis = ^PSDL_PenAxis; + PSDL_PenAxis = ^TSDL_PenAxis; + TSDL_PenAxis = type Integer; +const + SDL_PEN_AXIS_PRESSURE = TSDL_PenAxis(0); {*< Pen pressure. Unidirectional: 0 to 1.0 } + SDL_PEN_AXIS_XTILT = TSDL_PenAxis(1); {*< Pen horizontal tilt angle. Bidirectional: -90.0 to 90.0 (left-to-right). } + SDL_PEN_AXIS_YTILT = TSDL_PenAxis(2); {*< Pen vertical tilt angle. Bidirectional: -90.0 to 90.0 (top-to-down). } + SDL_PEN_AXIS_DISTANCE = TSDL_PenAxis(3); {*< Pen distance to drawing surface. Unidirectional: 0.0 to 1.0 } + SDL_PEN_AXIS_ROTATION = TSDL_PenAxis(4); {*< Pen barrel rotation. Bidirectional: -180 to 179.9 (clockwise, 0 is facing up, -180.0 is facing down). } + SDL_PEN_AXIS_SLIDER = TSDL_PenAxis(5); {*< Pen finger wheel or slider (e.g., Airbrush Pen). Unidirectional: 0 to 1.0 } + SDL_PEN_AXIS_TANGENTIAL_PRESSURE = TSDL_PenAxis(6); {*< Pressure from squeezing the pen ("barrel pressure"). } + SDL_PEN_AXIS_COUNT = TSDL_PenAxis(7); {*< Total known pen axis types in this version of SDL. This number may grow in future releases! } + diff --git a/units/SDL_power.inc b/units/SDL_power.inc new file mode 100644 index 0000000..7a2476f --- /dev/null +++ b/units/SDL_power.inc @@ -0,0 +1,64 @@ +{ + This file is part of: + + SDL3 for Pascal + (https://github.com/PascalGameDevelopment/SDL3-for-Pascal) + SPDX-License-Identifier: Zlib +} + +{* + * # CategoryPower + * + * SDL power management routines. + } + +{* + * The basic state for the system's power supply. + * + * These are results returned by SDL_GetPowerInfo(). + * + * \since This enum is available since SDL 3.1.3 + } +type + PPSDL_PowerState = ^PSDL_PowerState; + PSDL_PowerState = ^TSDL_PowerState; + TSDL_PowerState = type Integer; +const + SDL_POWERSTATE_ERROR = -1; {*< error determining power status } + SDL_POWERSTATE_UNKNOWN = TSDL_PowerState(0); {*< cannot determine power status } + SDL_POWERSTATE_ON_BATTERY = TSDL_PowerState(1); {*< Not plugged in, running on the battery } + SDL_POWERSTATE_NO_BATTERY = TSDL_PowerState(2); {*< Plugged in, no battery available } + SDL_POWERSTATE_CHARGING = TSDL_PowerState(3); {*< Plugged in, charging battery } + SDL_POWERSTATE_CHARGED = TSDL_PowerState(4); {*< Plugged in, battery charged } + +{* + * Get the current power supply details. + * + * You should never take a battery status as absolute truth. Batteries + * (especially failing batteries) are delicate hardware, and the values + * reported here are best estimates based on what that hardware reports. It's + * not uncommon for older batteries to lose stored power much faster than it + * reports, or completely drain when reporting it has 20 percent left, etc. + * + * Battery status can change at any time; if you are concerned with power + * state, you should call this function frequently, and perhaps ignore changes + * until they seem to be stable for a few seconds. + * + * It's possible a platform can only report battery percentage or time left + * but not both. + * + * \param seconds a Pointer filled in with the seconds of battery life left, + * or nil to ignore. This will be filled in with -1 if we + * can't determine a value or there is no battery. + * \param percent a Pointer filled in with the percentage of battery life + * left, between 0 and 100, or nil to ignore. This will be + * filled in with -1 we can't determine a value or there is no + * battery. + * \returns the current battery state or `SDL_POWERSTATE_ERROR` on failure; + * call SDL_GetError() for more information. + * + * \since This function is available since SDL 3.1.3. + } +function SDL_GetPowerInfo(seconds: pcint; percent: pcint): TSDL_PowerState; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetPowerInfo' {$ENDIF} {$ENDIF}; + diff --git a/units/SDL_render.inc b/units/SDL_render.inc index 4736ca2..cae8244 100644 --- a/units/SDL_render.inc +++ b/units/SDL_render.inc @@ -1540,9 +1540,8 @@ function SDL_RenderCoordinatesToWindow(renderer: PSDL_Renderer; x: cfloat; y: cf * * \sa SDL_RenderCoordinatesFromWindow } -{ #todo : SDL3-for-Pascal: Uncomment after publishing SDL_event.inc (defines PSDL_Event). } -//function SDL_ConvertEventToRenderCoordinates(renderer: PSDL_Renderer; event: PSDL_Event): cbool; cdecl; -// external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_ConvertEventToRenderCoordinates' {$ENDIF} {$ENDIF}; +function SDL_ConvertEventToRenderCoordinates(renderer: PSDL_Renderer; event: PSDL_Event): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_ConvertEventToRenderCoordinates' {$ENDIF} {$ENDIF}; {* * Set the drawing area for rendering on the current target. diff --git a/units/SDL_scancode.inc b/units/SDL_scancode.inc new file mode 100644 index 0000000..5e93342 --- /dev/null +++ b/units/SDL_scancode.inc @@ -0,0 +1,401 @@ +{ + This file is part of: + + SDL3 for Pascal + (https://github.com/PascalGameDevelopment/SDL3-for-Pascal) + SPDX-License-Identifier: Zlib +} + +{* + * # CategoryScancode + * + * Defines keyboard scancodes. + } + +{** The SDL keyboard scancode representation. + * + * An SDL scancode is the physical representation of a key on the keyboard, + * independent of language and keyboard mapping. + * + * Values of this type are used to represent keyboard keys, among other places + * in the `scancode` field of the SDL_KeyboardEvent structure. + * + * The values in this enumeration are based on the USB usage page standard: + * https://usb.org/sites/default/files/hut1_5.pdf + * + * \since This enum is available since SDL 3.1.3. + } +type + PPSDL_Scancode = ^PSDL_Scancode; + PSDL_Scancode = ^TSDL_Scancode; + TSDL_Scancode = Integer; +const + SDL_SCANCODE_UNKNOWN = TSDL_Scancode(0); + + {* + * \name Usage page 0x07 + * + * These values are from usage page 0x07 (USB keyboard page). + } + + SDL_SCANCODE_A = TSDL_Scancode(4); + SDL_SCANCODE_B = TSDL_Scancode(5); + SDL_SCANCODE_C = TSDL_Scancode(6); + SDL_SCANCODE_D = TSDL_Scancode(7); + SDL_SCANCODE_E = TSDL_Scancode(8); + SDL_SCANCODE_F = TSDL_Scancode(9); + SDL_SCANCODE_G = TSDL_Scancode(10); + SDL_SCANCODE_H = TSDL_Scancode(11); + SDL_SCANCODE_I = TSDL_Scancode(12); + SDL_SCANCODE_J = TSDL_Scancode(13); + SDL_SCANCODE_K = TSDL_Scancode(14); + SDL_SCANCODE_L = TSDL_Scancode(15); + SDL_SCANCODE_M = TSDL_Scancode(16); + SDL_SCANCODE_N = TSDL_Scancode(17); + SDL_SCANCODE_O = TSDL_Scancode(18); + SDL_SCANCODE_P = TSDL_Scancode(19); + SDL_SCANCODE_Q = TSDL_Scancode(20); + SDL_SCANCODE_R = TSDL_Scancode(21); + SDL_SCANCODE_S = TSDL_Scancode(22); + SDL_SCANCODE_T = TSDL_Scancode(23); + SDL_SCANCODE_U = TSDL_Scancode(24); + SDL_SCANCODE_V = TSDL_Scancode(25); + SDL_SCANCODE_W = TSDL_Scancode(26); + SDL_SCANCODE_X = TSDL_Scancode(27); + SDL_SCANCODE_Y = TSDL_Scancode(28); + SDL_SCANCODE_Z = TSDL_Scancode(29); + + SDL_SCANCODE_1 = TSDL_Scancode(30); + SDL_SCANCODE_2 = TSDL_Scancode(31); + SDL_SCANCODE_3 = TSDL_Scancode(32); + SDL_SCANCODE_4 = TSDL_Scancode(33); + SDL_SCANCODE_5 = TSDL_Scancode(34); + SDL_SCANCODE_6 = TSDL_Scancode(35); + SDL_SCANCODE_7 = TSDL_Scancode(36); + SDL_SCANCODE_8 = TSDL_Scancode(37); + SDL_SCANCODE_9 = TSDL_Scancode(38); + SDL_SCANCODE_0 = TSDL_Scancode(39); + + SDL_SCANCODE_RETURN = TSDL_Scancode(40); + SDL_SCANCODE_ESCAPE = TSDL_Scancode(41); + SDL_SCANCODE_BACKSPACE = TSDL_Scancode(42); + SDL_SCANCODE_TAB = TSDL_Scancode(43); + SDL_SCANCODE_SPACE = TSDL_Scancode(44); + + SDL_SCANCODE_MINUS = TSDL_Scancode(45); + SDL_SCANCODE_EQUALS = TSDL_Scancode(46); + SDL_SCANCODE_LEFTBRACKET = TSDL_Scancode(47); + SDL_SCANCODE_RIGHTBRACKET = TSDL_Scancode(48); + SDL_SCANCODE_BACKSLASH = TSDL_Scancode(49); {*< Located at the lower left of the return + * key on ISO keyboards and at the right end + * of the QWERTY row on ANSI keyboards. + * Produces REVERSE SOLIDUS (backslash) and + * VERTICAL LINE in a US layout, REVERSE + * SOLIDUS and VERTICAL LINE in a UK Mac + * layout, NUMBER SIGN and TILDE in a UK + * Windows layout, DOLLAR SIGN and POUND SIGN + * in a Swiss German layout, NUMBER SIGN and + * APOSTROPHE in a German layout, GRAVE + * ACCENT and POUND SIGN in a French Mac + * layout, and ASTERISK and MICRO SIGN in a + * French Windows layout. + } + SDL_SCANCODE_NONUSHASH = TSDL_Scancode(50); {*< ISO USB keyboards actually use this code + * instead of 49 for the same key, but all + * OSes I've seen treat the two codes + * identically. So, as an implementor, unless + * your keyboard generates both of those + * codes and your OS treats them differently, + * you should generate SDL_SCANCODE_BACKSLASH + * instead of this code. As a user, you + * should not rely on this code because SDL + * will never generate it with most (all?) + * keyboards. + } + SDL_SCANCODE_SEMICOLON = TSDL_Scancode(51); + SDL_SCANCODE_APOSTROPHE = TSDL_Scancode(52); + SDL_SCANCODE_GRAVE = TSDL_Scancode(53); {*< Located in the top left corner (on both ANSI + * and ISO keyboards). Produces GRAVE ACCENT and + * TILDE in a US Windows layout and in US and UK + * Mac layouts on ANSI keyboards, GRAVE ACCENT + * and NOT SIGN in a UK Windows layout, SECTION + * SIGN and PLUS-MINUS SIGN in US and UK Mac + * layouts on ISO keyboards, SECTION SIGN and + * DEGREE SIGN in a Swiss German layout (Mac: + * only on ISO keyboards), CIRCUMFLEX ACCENT and + * DEGREE SIGN in a German layout (Mac: only on + * ISO keyboards), SUPERSCRIPT TWO and TILDE in a + * French Windows layout, COMMERCIAL AT and + * NUMBER SIGN in a French Mac layout on ISO + * keyboards, and LESS-THAN SIGN and GREATER-THAN + * SIGN in a Swiss German, German, or French Mac + * layout on ANSI keyboards. + } + SDL_SCANCODE_COMMA = TSDL_Scancode(54); + SDL_SCANCODE_PERIOD = TSDL_Scancode(55); + SDL_SCANCODE_SLASH = TSDL_Scancode(56); + + SDL_SCANCODE_CAPSLOCK = TSDL_Scancode(57); + + SDL_SCANCODE_F1 = TSDL_Scancode(58); + SDL_SCANCODE_F2 = TSDL_Scancode(59); + SDL_SCANCODE_F3 = TSDL_Scancode(60); + SDL_SCANCODE_F4 = TSDL_Scancode(61); + SDL_SCANCODE_F5 = TSDL_Scancode(62); + SDL_SCANCODE_F6 = TSDL_Scancode(63); + SDL_SCANCODE_F7 = TSDL_Scancode(64); + SDL_SCANCODE_F8 = TSDL_Scancode(65); + SDL_SCANCODE_F9 = TSDL_Scancode(66); + SDL_SCANCODE_F10 = TSDL_Scancode(67); + SDL_SCANCODE_F11 = TSDL_Scancode(68); + SDL_SCANCODE_F12 = TSDL_Scancode(69); + + SDL_SCANCODE_PRINTSCREEN = TSDL_Scancode(70); + SDL_SCANCODE_SCROLLLOCK = TSDL_Scancode(71); + SDL_SCANCODE_PAUSE = TSDL_Scancode(72); + SDL_SCANCODE_INSERT = TSDL_Scancode(73); {*< insert on PC, help on some Mac keyboards (but + does send code 73, not 117) } + SDL_SCANCODE_HOME = TSDL_Scancode(74); + SDL_SCANCODE_PAGEUP = TSDL_Scancode(75); + SDL_SCANCODE_DELETE = TSDL_Scancode(76); + SDL_SCANCODE_END = TSDL_Scancode(77); + SDL_SCANCODE_PAGEDOWN = TSDL_Scancode(78); + SDL_SCANCODE_RIGHT = TSDL_Scancode(79); + SDL_SCANCODE_LEFT = TSDL_Scancode(80); + SDL_SCANCODE_DOWN = TSDL_Scancode(81); + SDL_SCANCODE_UP = TSDL_Scancode(82); + + SDL_SCANCODE_NUMLOCKCLEAR = TSDL_Scancode(83); {*< num lock on PC, clear on Mac keyboards + } + SDL_SCANCODE_KP_DIVIDE = TSDL_Scancode(84); + SDL_SCANCODE_KP_MULTIPLY = TSDL_Scancode(85); + SDL_SCANCODE_KP_MINUS = TSDL_Scancode(86); + SDL_SCANCODE_KP_PLUS = TSDL_Scancode(87); + SDL_SCANCODE_KP_ENTER = TSDL_Scancode(88); + SDL_SCANCODE_KP_1 = TSDL_Scancode(89); + SDL_SCANCODE_KP_2 = TSDL_Scancode(90); + SDL_SCANCODE_KP_3 = TSDL_Scancode(91); + SDL_SCANCODE_KP_4 = TSDL_Scancode(92); + SDL_SCANCODE_KP_5 = TSDL_Scancode(93); + SDL_SCANCODE_KP_6 = TSDL_Scancode(94); + SDL_SCANCODE_KP_7 = TSDL_Scancode(95); + SDL_SCANCODE_KP_8 = TSDL_Scancode(96); + SDL_SCANCODE_KP_9 = TSDL_Scancode(97); + SDL_SCANCODE_KP_0 = TSDL_Scancode(98); + SDL_SCANCODE_KP_PERIOD = TSDL_Scancode(99); + + SDL_SCANCODE_NONUSBACKSLASH = TSDL_Scancode(100); {*< This is the additional key that ISO + * keyboards have over ANSI ones, + * located between left shift and Y. + * Produces GRAVE ACCENT and TILDE in a + * US or UK Mac layout, REVERSE SOLIDUS + * (backslash) and VERTICAL LINE in a + * US or UK Windows layout, and + * LESS-THAN SIGN and GREATER-THAN SIGN + * in a Swiss German, German, or French + * layout. } + SDL_SCANCODE_APPLICATION = TSDL_Scancode(101); {*< windows contextual menu, compose } + SDL_SCANCODE_POWER = TSDL_Scancode(102); {*< The USB document says this is a status flag, + * not a physical key - but some Mac keyboards + * do have a power key. } + SDL_SCANCODE_KP_EQUALS = TSDL_Scancode(103); + SDL_SCANCODE_F13 = TSDL_Scancode(104); + SDL_SCANCODE_F14 = TSDL_Scancode(105); + SDL_SCANCODE_F15 = TSDL_Scancode(106); + SDL_SCANCODE_F16 = TSDL_Scancode(107); + SDL_SCANCODE_F17 = TSDL_Scancode(108); + SDL_SCANCODE_F18 = TSDL_Scancode(109); + SDL_SCANCODE_F19 = TSDL_Scancode(110); + SDL_SCANCODE_F20 = TSDL_Scancode(111); + SDL_SCANCODE_F21 = TSDL_Scancode(112); + SDL_SCANCODE_F22 = TSDL_Scancode(113); + SDL_SCANCODE_F23 = TSDL_Scancode(114); + SDL_SCANCODE_F24 = TSDL_Scancode(115); + SDL_SCANCODE_EXECUTE = TSDL_Scancode(116); + SDL_SCANCODE_HELP = TSDL_Scancode(117); {*< AL Integrated Help Center } + SDL_SCANCODE_MENU = TSDL_Scancode(118); {*< Menu (show menu) } + SDL_SCANCODE_SELECT = TSDL_Scancode(119); + SDL_SCANCODE_STOP = TSDL_Scancode(120); {*< AC Stop } + SDL_SCANCODE_AGAIN = TSDL_Scancode(121); {*< AC Redo/Repeat } + SDL_SCANCODE_UNDO = TSDL_Scancode(122); {*< AC Undo } + SDL_SCANCODE_CUT = TSDL_Scancode(123); {*< AC Cut } + SDL_SCANCODE_COPY = TSDL_Scancode(124); {*< AC Copy } + SDL_SCANCODE_PASTE = TSDL_Scancode(125); {*< AC Paste } + SDL_SCANCODE_FIND = TSDL_Scancode(126); {*< AC Find } + SDL_SCANCODE_MUTE = TSDL_Scancode(127); + SDL_SCANCODE_VOLUMEUP = TSDL_Scancode(128); + SDL_SCANCODE_VOLUMEDOWN = TSDL_Scancode(129); +{ not sure whether there's a reason to enable these } +{ SDL_SCANCODE_LOCKINGCAPSLOCK = 130, } +{ SDL_SCANCODE_LOCKINGNUMLOCK = 131, } +{ SDL_SCANCODE_LOCKINGSCROLLLOCK = 132, } + SDL_SCANCODE_KP_COMMA = TSDL_Scancode(133); + SDL_SCANCODE_KP_EQUALSAS400 = TSDL_Scancode(134); + + SDL_SCANCODE_INTERNATIONAL1 = TSDL_Scancode(135); {*< used on Asian keyboards, see + footnotes in USB doc } + SDL_SCANCODE_INTERNATIONAL2 = TSDL_Scancode(136); + SDL_SCANCODE_INTERNATIONAL3 = TSDL_Scancode(137); {*< Yen } + SDL_SCANCODE_INTERNATIONAL4 = TSDL_Scancode(138); + SDL_SCANCODE_INTERNATIONAL5 = TSDL_Scancode(139); + SDL_SCANCODE_INTERNATIONAL6 = TSDL_Scancode(140); + SDL_SCANCODE_INTERNATIONAL7 = TSDL_Scancode(141); + SDL_SCANCODE_INTERNATIONAL8 = TSDL_Scancode(142); + SDL_SCANCODE_INTERNATIONAL9 = TSDL_Scancode(143); + SDL_SCANCODE_LANG1 = TSDL_Scancode(144); {*< Hangul/English toggle } + SDL_SCANCODE_LANG2 = TSDL_Scancode(145); {*< Hanja conversion } + SDL_SCANCODE_LANG3 = TSDL_Scancode(146); {*< Katakana } + SDL_SCANCODE_LANG4 = TSDL_Scancode(147); {*< Hiragana } + SDL_SCANCODE_LANG5 = TSDL_Scancode(148); {*< Zenkaku/Hankaku } + SDL_SCANCODE_LANG6 = TSDL_Scancode(149); {*< reserved } + SDL_SCANCODE_LANG7 = TSDL_Scancode(150); {*< reserved } + SDL_SCANCODE_LANG8 = TSDL_Scancode(151); {*< reserved } + SDL_SCANCODE_LANG9 = TSDL_Scancode(152); {*< reserved } + + SDL_SCANCODE_ALTERASE = TSDL_Scancode(153); {*< Erase-Eaze } + SDL_SCANCODE_SYSREQ = TSDL_Scancode(154); + SDL_SCANCODE_CANCEL = TSDL_Scancode(155); {*< AC Cancel } + SDL_SCANCODE_CLEAR = TSDL_Scancode(156); + SDL_SCANCODE_PRIOR = TSDL_Scancode(157); + SDL_SCANCODE_RETURN2 = TSDL_Scancode(158); + SDL_SCANCODE_SEPARATOR = TSDL_Scancode(159); + SDL_SCANCODE_OUT = TSDL_Scancode(160); + SDL_SCANCODE_OPER = TSDL_Scancode(161); + SDL_SCANCODE_CLEARAGAIN = TSDL_Scancode(162); + SDL_SCANCODE_CRSEL = TSDL_Scancode(163); + SDL_SCANCODE_EXSEL = TSDL_Scancode(164); + + SDL_SCANCODE_KP_00 = TSDL_Scancode(176); + SDL_SCANCODE_KP_000 = TSDL_Scancode(177); + SDL_SCANCODE_THOUSANDSSEPARATOR = TSDL_Scancode(178); + SDL_SCANCODE_DECIMALSEPARATOR = TSDL_Scancode(179); + SDL_SCANCODE_CURRENCYUNIT = TSDL_Scancode(180); + SDL_SCANCODE_CURRENCYSUBUNIT = TSDL_Scancode(181); + SDL_SCANCODE_KP_LEFTPAREN = TSDL_Scancode(182); + SDL_SCANCODE_KP_RIGHTPAREN = TSDL_Scancode(183); + SDL_SCANCODE_KP_LEFTBRACE = TSDL_Scancode(184); + SDL_SCANCODE_KP_RIGHTBRACE = TSDL_Scancode(185); + SDL_SCANCODE_KP_TAB = TSDL_Scancode(186); + SDL_SCANCODE_KP_BACKSPACE = TSDL_Scancode(187); + SDL_SCANCODE_KP_A = TSDL_Scancode(188); + SDL_SCANCODE_KP_B = TSDL_Scancode(189); + SDL_SCANCODE_KP_C = TSDL_Scancode(190); + SDL_SCANCODE_KP_D = TSDL_Scancode(191); + SDL_SCANCODE_KP_E = TSDL_Scancode(192); + SDL_SCANCODE_KP_F = TSDL_Scancode(193); + SDL_SCANCODE_KP_XOR = TSDL_Scancode(194); + SDL_SCANCODE_KP_POWER = TSDL_Scancode(195); + SDL_SCANCODE_KP_PERCENT = TSDL_Scancode(196); + SDL_SCANCODE_KP_LESS = TSDL_Scancode(197); + SDL_SCANCODE_KP_GREATER = TSDL_Scancode(198); + SDL_SCANCODE_KP_AMPERSAND = TSDL_Scancode(199); + SDL_SCANCODE_KP_DBLAMPERSAND = TSDL_Scancode(200); + SDL_SCANCODE_KP_VERTICALBAR = TSDL_Scancode(201); + SDL_SCANCODE_KP_DBLVERTICALBAR = TSDL_Scancode(202); + SDL_SCANCODE_KP_COLON = TSDL_Scancode(203); + SDL_SCANCODE_KP_HASH = TSDL_Scancode(204); + SDL_SCANCODE_KP_SPACE = TSDL_Scancode(205); + SDL_SCANCODE_KP_AT = TSDL_Scancode(206); + SDL_SCANCODE_KP_EXCLAM = TSDL_Scancode(207); + SDL_SCANCODE_KP_MEMSTORE = TSDL_Scancode(208); + SDL_SCANCODE_KP_MEMRECALL = TSDL_Scancode(209); + SDL_SCANCODE_KP_MEMCLEAR = TSDL_Scancode(210); + SDL_SCANCODE_KP_MEMADD = TSDL_Scancode(211); + SDL_SCANCODE_KP_MEMSUBTRACT = TSDL_Scancode(212); + SDL_SCANCODE_KP_MEMMULTIPLY = TSDL_Scancode(213); + SDL_SCANCODE_KP_MEMDIVIDE = TSDL_Scancode(214); + SDL_SCANCODE_KP_PLUSMINUS = TSDL_Scancode(215); + SDL_SCANCODE_KP_CLEAR = TSDL_Scancode(216); + SDL_SCANCODE_KP_CLEARENTRY = TSDL_Scancode(217); + SDL_SCANCODE_KP_BINARY = TSDL_Scancode(218); + SDL_SCANCODE_KP_OCTAL = TSDL_Scancode(219); + SDL_SCANCODE_KP_DECIMAL = TSDL_Scancode(220); + SDL_SCANCODE_KP_HEXADECIMAL = TSDL_Scancode(221); + + SDL_SCANCODE_LCTRL = TSDL_Scancode(224); + SDL_SCANCODE_LSHIFT = TSDL_Scancode(225); + SDL_SCANCODE_LALT = TSDL_Scancode(226); {*< alt, option } + SDL_SCANCODE_LGUI = TSDL_Scancode(227); {*< windows, command (apple), meta } + SDL_SCANCODE_RCTRL = TSDL_Scancode(228); + SDL_SCANCODE_RSHIFT = TSDL_Scancode(229); + SDL_SCANCODE_RALT = TSDL_Scancode(230); {*< alt gr, option } + SDL_SCANCODE_RGUI = TSDL_Scancode(231); {*< windows, command (apple), meta } + + SDL_SCANCODE_MODE = TSDL_Scancode(257); {*< I'm not sure if this is really not covered + * by any of the above, but since there's a + * special SDL_KMOD_MODE for it I'm adding it here + } + + { Usage page 0x07 } + + {* + * \name Usage page 0x0C + * + * These values are mapped from usage page 0x0C (USB consumer page). + * + * There are way more keys in the spec than we can represent in the + * current scancode range, so pick the ones that commonly come up in + * real world usage. + } + + SDL_SCANCODE_SLEEP = TSDL_Scancode(258); {*< Sleep } + SDL_SCANCODE_WAKE = TSDL_Scancode(259); {*< Wake } + + SDL_SCANCODE_CHANNEL_INCREMENT = TSDL_Scancode(260); {*< Channel Increment } + SDL_SCANCODE_CHANNEL_DECREMENT = TSDL_Scancode(261); {*< Channel Decrement } + + SDL_SCANCODE_MEDIA_PLAY = TSDL_Scancode(262); {*< Play } + SDL_SCANCODE_MEDIA_PAUSE = TSDL_Scancode(263); {*< Pause } + SDL_SCANCODE_MEDIA_RECORD = TSDL_Scancode(264); {*< Record } + SDL_SCANCODE_MEDIA_FAST_FORWARD = TSDL_Scancode(265); {*< Fast Forward } + SDL_SCANCODE_MEDIA_REWIND = TSDL_Scancode(266); {*< Rewind } + SDL_SCANCODE_MEDIA_NEXT_TRACK = TSDL_Scancode(267); {*< Next Track } + SDL_SCANCODE_MEDIA_PREVIOUS_TRACK = TSDL_Scancode(268); {*< Previous Track } + SDL_SCANCODE_MEDIA_STOP = TSDL_Scancode(269); {*< Stop } + SDL_SCANCODE_MEDIA_EJECT = TSDL_Scancode(270); {*< Eject } + SDL_SCANCODE_MEDIA_PLAY_PAUSE = TSDL_Scancode(271); {*< Play / Pause } + SDL_SCANCODE_MEDIA_SELECT = TSDL_Scancode(272); { Media Select } + + SDL_SCANCODE_AC_NEW = TSDL_Scancode(273); {*< AC New } + SDL_SCANCODE_AC_OPEN = TSDL_Scancode(274); {*< AC Open } + SDL_SCANCODE_AC_CLOSE = TSDL_Scancode(275); {*< AC Close } + SDL_SCANCODE_AC_EXIT = TSDL_Scancode(276); {*< AC Exit } + SDL_SCANCODE_AC_SAVE = TSDL_Scancode(277); {*< AC Save } + SDL_SCANCODE_AC_PRINT = TSDL_Scancode(278); {*< AC Print } + SDL_SCANCODE_AC_PROPERTIES = TSDL_Scancode(279); {*< AC Properties } + + SDL_SCANCODE_AC_SEARCH = TSDL_Scancode(280); {*< AC Search } + SDL_SCANCODE_AC_HOME = TSDL_Scancode(281); {*< AC Home } + SDL_SCANCODE_AC_BACK = TSDL_Scancode(282); {*< AC Back } + SDL_SCANCODE_AC_FORWARD = TSDL_Scancode(283); {*< AC Forward } + SDL_SCANCODE_AC_STOP = TSDL_Scancode(284); {*< AC Stop } + SDL_SCANCODE_AC_REFRESH = TSDL_Scancode(285); {*< AC Refresh } + SDL_SCANCODE_AC_BOOKMARKS = TSDL_Scancode(286); {*< AC Bookmarks } + + { Usage page 0x0C } + + {* + * \name Mobile keys + * + * These are values that are often used on mobile phones. + } + + SDL_SCANCODE_SOFTLEFT = TSDL_Scancode(287); {*< Usually situated below the display on phones and + used as a multi-function feature key for selecting + a software defined function shown on the bottom left + of the display. } + SDL_SCANCODE_SOFTRIGHT = TSDL_Scancode(288); {*< Usually situated below the display on phones and + used as a multi-function feature key for selecting + a software defined function shown on the bottom right + of the display. } + SDL_SCANCODE_CALL = TSDL_Scancode(289); {*< Used for accepting phone calls. } + SDL_SCANCODE_ENDCALL = TSDL_Scancode(290); {*< Used for rejecting phone calls. } + + { Mobile keys } + + { Add any other keys here. } + + SDL_SCANCODE_RESERVED = TSDL_Scancode(400); {*< 400-500 reserved for dynamic keycodes } + + SDL_SCANCODE_COUNT = TSDL_Scancode(512); {*< not a key, just marks the number of scancodes for array bounds } + diff --git a/units/SDL_sensor.inc b/units/SDL_sensor.inc new file mode 100644 index 0000000..6472f69 --- /dev/null +++ b/units/SDL_sensor.inc @@ -0,0 +1,296 @@ +{ + This file is part of: + + SDL3 for Pascal + (https://github.com/PascalGameDevelopment/SDL3-for-Pascal) + SPDX-License-Identifier: Zlib +} + +{* + * # CategorySensor + * + * SDL sensor management. + * + * In order to use these functions, SDL_Init() must have been called with the + * SDL_INIT_SENSOR flag. This causes SDL to scan the system for sensors, and + * load appropriate drivers. + } + +type + PPSDL_Sensor = ^PSDL_Sensor; + PSDL_Sensor = type Pointer; + +{* + * This is a unique ID for a sensor for the time it is connected to the + * system, and is never reused for the lifetime of the application. + * + * The value 0 is an invalid ID. + * + * \since This datatype is available since SDL 3.1.3. + } +type + PPSDL_SensorID = ^PSDL_SensorID; + PSDL_SensorID = ^TSDL_SensorID; + TSDL_SensorID = cuint32; + +{* + * A constant to represent standard gravity for accelerometer sensors. + * + * The accelerometer returns the current acceleration in SI meters per second + * squared. This measurement includes the force of gravity, so a device at + * rest will have an value of SDL_STANDARD_GRAVITY away from the center of the + * earth, which is a positive Y value. + * + * \since This macro is available since SDL 3.1.3. + } +const + SDL_STANDARD_GRAVITY = cfloat(9.80665); + +{* + * The different sensors defined by SDL. + * + * Additional sensors may be available, using platform dependent semantics. + * + * Here are the additional Android sensors: + * + * https://developer.android.com/reference/android/hardware/SensorEvent.html#values + * + * Accelerometer sensor notes: + * + * The accelerometer returns the current acceleration in SI meters per second + * squared. This measurement includes the force of gravity, so a device at + * rest will have an value of SDL_STANDARD_GRAVITY away from the center of the + * earth, which is a positive Y value. + * + * - `values[0]`: Acceleration on the x axis + * - `values[1]`: Acceleration on the y axis + * - `values[2]`: Acceleration on the z axis + * + * For phones and tablets held in natural orientation and game controllers + * held in front of you, the axes are defined as follows: + * + * - -X ... +X: left ... right + * - -Y ... +Y: bottom ... top + * - -Z ... +Z: farther ... closer + * + * The accelerometer axis data is not changed when the device is rotated. + * + * Gyroscope sensor notes: + * + * The gyroscope returns the current rate of rotation in radians per second. + * The rotation is positive in the counter-clockwise direction. That is, an + * observer looking from a positive location on one of the axes would see + * positive rotation on that axis when it appeared to be rotating + * counter-clockwise. + * + * - `values[0]`: Angular speed around the x axis (pitch) + * - `values[1]`: Angular speed around the y axis (yaw) + * - `values[2]`: Angular speed around the z axis (roll) + * + * For phones and tablets held in natural orientation and game controllers + * held in front of you, the axes are defined as follows: + * + * - -X ... +X: left ... right + * - -Y ... +Y: bottom ... top + * - -Z ... +Z: farther ... closer + * + * The gyroscope axis data is not changed when the device is rotated. + * + * \since This enum is available since SDL 3.1.3. + * + * \sa SDL_GetCurrentDisplayOrientation + } +type + PPSDL_SensorType = ^PSDL_SensorType; + PSDL_SensorType = ^TSDL_SensorType; + TSDL_SensorType = type Integer; +const + SDL_SENSOR_INVALID = TSDL_SensorType(-1); {*< Returned for an invalid sensor } + SDL_SENSOR_UNKNOWN = TSDL_SensorType(0); {*< Unknown sensor type } + SDL_SENSOR_ACCEL = TSDL_SensorType(1); {*< Accelerometer } + SDL_SENSOR_GYRO = TSDL_SensorType(2); {*< Gyroscope } + SDL_SENSOR_ACCEL_L = TSDL_SensorType(3); {*< Accelerometer for left Joy-Con controller and Wii nunchuk } + SDL_SENSOR_GYRO_L = TSDL_SensorType(4); {*< Gyroscope for left Joy-Con controller } + SDL_SENSOR_ACCEL_R = TSDL_SensorType(5); {*< Accelerometer for right Joy-Con controller } + SDL_SENSOR_GYRO_R = TSDL_SensorType(6); {*< Gyroscope for right Joy-Con controller } + +{ Function prototypes } + +{* + * Get a list of currently connected sensors. + * + * \param count a Pointer filled in with the number of sensors returned, may + * be nil. + * \returns a 0 terminated array of sensor instance IDs or nil on failure; + * call SDL_GetError() for more information. This should be freed + * with SDL_free() when it is no longer needed. + * + * \since This function is available since SDL 3.1.3. + } +function SDL_GetSensors(count: pcint): PSDL_SensorID; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetSensors' {$ENDIF} {$ENDIF}; + +{* + * Get the implementation dependent name of a sensor. + * + * This can be called before any sensors are opened. + * + * \param instance_id the sensor instance ID. + * \returns the sensor name, or nil if `instance_id` is not valid. + * + * \since This function is available since SDL 3.1.3. + } +function SDL_GetSensorNameForID(instance_id: TSDL_SensorID): PAnsiChar; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetSensorNameForID' {$ENDIF} {$ENDIF}; + +{* + * Get the type of a sensor. + * + * This can be called before any sensors are opened. + * + * \param instance_id the sensor instance ID. + * \returns the SDL_SensorType, or `SDL_SENSOR_INVALID` if `instance_id` is + * not valid. + * + * \since This function is available since SDL 3.1.3. + } +function SDL_GetSensorTypeForID(instance_id: TSDL_SensorID): TSDL_SensorType; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetSensorTypeForID' {$ENDIF} {$ENDIF}; + +{* + * Get the platform dependent type of a sensor. + * + * This can be called before any sensors are opened. + * + * \param instance_id the sensor instance ID. + * \returns the sensor platform dependent type, or -1 if `instance_id` is not + * valid. + * + * \since This function is available since SDL 3.1.3. + } +function SDL_GetSensorNonPortableTypeForID(instance_id: TSDL_SensorID): cint; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetSensorNonPortableTypeForID' {$ENDIF} {$ENDIF}; + +{* + * Open a sensor for use. + * + * \param instance_id the sensor instance ID. + * \returns an SDL_Sensor object or nil on failure; call SDL_GetError() for + * more information. + * + * \since This function is available since SDL 3.1.3. + } +function SDL_OpenSensor(instance_id: TSDL_SensorID): PSDL_Sensor; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_OpenSensor' {$ENDIF} {$ENDIF}; + +{* + * Return the SDL_Sensor associated with an instance ID. + * + * \param instance_id the sensor instance ID. + * \returns an SDL_Sensor object or nil on failure; call SDL_GetError() for + * more information. + * + * \since This function is available since SDL 3.1.3. + } +function SDL_GetSensorFromID(instance_id: TSDL_SensorID): PSDL_Sensor; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetSensorFromID' {$ENDIF} {$ENDIF}; + +{* + * Get the properties associated with a sensor. + * + * \param sensor the SDL_Sensor object. + * \returns a valid property ID on success or 0 on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 3.1.3. + } +function SDL_GetSensorProperties(sensor: PSDL_Sensor): TSDL_PropertiesID; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetSensorProperties' {$ENDIF} {$ENDIF}; + +{* + * Get the implementation dependent name of a sensor. + * + * \param sensor the SDL_Sensor object. + * \returns the sensor name or nil on failure; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 3.1.3. + } +function SDL_GetSensorName(sensor: PSDL_Sensor): PAnsiChar; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetSensorName' {$ENDIF} {$ENDIF}; + +{* + * Get the type of a sensor. + * + * \param sensor the SDL_Sensor object to inspect. + * \returns the SDL_SensorType type, or `SDL_SENSOR_INVALID` if `sensor` is + * nil. + * + * \since This function is available since SDL 3.1.3. + } +function SDL_GetSensorType(sensor: PSDL_Sensor): TSDL_SensorType; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetSensorType' {$ENDIF} {$ENDIF}; + +{* + * Get the platform dependent type of a sensor. + * + * \param sensor the SDL_Sensor object to inspect. + * \returns the sensor platform dependent type, or -1 if `sensor` is nil. + * + * \since This function is available since SDL 3.1.3. + } +function SDL_GetSensorNonPortableType(sensor: PSDL_Sensor): cint; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetSensorNonPortableType' {$ENDIF} {$ENDIF}; + +{* + * Get the instance ID of a sensor. + * + * \param sensor the SDL_Sensor object to inspect. + * \returns the sensor instance ID, or 0 on failure; call SDL_GetError() for + * more information. + * + * \since This function is available since SDL 3.1.3. + } +function SDL_GetSensorID(sensor: PSDL_Sensor): TSDL_SensorID; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetSensorID' {$ENDIF} {$ENDIF}; + +{* + * Get the current state of an opened sensor. + * + * The number of values and interpretation of the data is sensor dependent. + * + * \param sensor the SDL_Sensor object to query. + * \param data a Pointer filled with the current sensor state. + * \param num_values the number of values to write to data. + * \returns true on success or false on failure; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 3.1.3. + } +function SDL_GetSensorData(sensor: PSDL_Sensor; data: pcfloat; num_values: cint): cbool; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetSensorData' {$ENDIF} {$ENDIF}; + +{* + * Close a sensor previously opened with SDL_OpenSensor(). + * + * \param sensor the SDL_Sensor object to close. + * + * \since This function is available since SDL 3.1.3. + } +procedure SDL_CloseSensor(sensor: PSDL_Sensor); cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_CloseSensor' {$ENDIF} {$ENDIF}; + +{* + * Update the current state of the open sensors. + * + * This is called automatically by the event loop if sensor events are + * enabled. + * + * This needs to be called from the thread that initialized the sensor + * subsystem. + * + * \since This function is available since SDL 3.1.3. + } +procedure SDL_UpdateSensors; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_UpdateSensors' {$ENDIF} {$ENDIF}; + diff --git a/units/SDL_touch.inc b/units/SDL_touch.inc new file mode 100644 index 0000000..0ce0228 --- /dev/null +++ b/units/SDL_touch.inc @@ -0,0 +1,119 @@ +{ + This file is part of: + + SDL3 for Pascal + (https://github.com/PascalGameDevelopment/SDL3-for-Pascal) + SPDX-License-Identifier: Zlib +} + +{* + * # CategoryTouch + * + * SDL touch management. + } + +type + PPSDL_TouchID = ^PSDL_TouchID; + PSDL_TouchID = ^TSDL_TouchID; + TSDL_TouchID = cuint64; + + PPSDL_FingerID = ^PSDL_FingerID; + PSDL_FingerID = ^TSDL_FingerID; + TSDL_FingerID = cuint64; + +type + PPSDL_TouchDeviceType = ^PSDL_TouchDeviceType; + PSDL_TouchDeviceType = ^TSDL_TouchDeviceType; + TSDL_TouchDeviceType = type Integer; +const + SDL_TOUCH_DEVICE_INVALID = TSDL_TouchDeviceType(-1); + SDL_TOUCH_DEVICE_DIRECT = TSDL_TouchDeviceType(0); { touch screen with window-relative coordinates } + SDL_TOUCH_DEVICE_INDIRECT_ABSOLUTE = TSDL_TouchDeviceType(1); { trackpad with absolute device coordinates } + SDL_TOUCH_DEVICE_INDIRECT_RELATIVE = TSDL_TouchDeviceType(2); { trackpad with screen cursor-relative coordinates } + +{* + * Data about a single finger in a multitouch event. + * + * Each touch even is a collection of fingers that are simultaneously in + * contact with the touch device (so a "touch" can be a "multitouch," in + * reality), and this struct reports details of the specific fingers. + * + * \since This struct is available since SDL 3.1.3. + * + * \sa SDL_GetTouchFingers + } +type + PPSDL_Finger = ^PSDL_Finger; + PSDL_Finger = ^TSDL_Finger; + TSDL_Finger = record + id: TSDL_FingerID; {*< the finger ID } + x: cfloat; {*< the x-axis location of the touch event, normalized (0...1) } + y: cfloat; {*< the y-axis location of the touch event, normalized (0...1) } + pressure: cfloat; {*< the quantity of pressure applied, normalized (0...1) } + end; + +{ #todo : SDL3-for-Pascal: Translate macro } +{ Used as the device ID for mouse events simulated with touch input } +{ #define SDL_TOUCH_MOUSEID ((SDL_MouseID)-1) } + +{ #todo : SDL3-for-Pascal: Translate macro } +{ Used as the SDL_TouchID for touch events simulated with mouse input } +{ #define SDL_MOUSE_TOUCHID ((SDL_TouchID)-1) } + +{* + * Get a list of registered touch devices. + * + * On some platforms SDL first sees the touch device if it was actually used. + * Therefore the returned list might be empty, although devices are available. + * After using all devices at least once the number will be correct. + * + * \param count a Pointer filled in with the number of devices returned, may + * be nil. + * \returns a 0 terminated array of touch device IDs or nil on failure; call + * SDL_GetError() for more information. This should be freed with + * SDL_free() when it is no longer needed. + * + * \since This function is available since SDL 3.1.3. + } +function SDL_GetTouchDevices(count: pcint): PSDL_TouchID; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetTouchDevices' {$ENDIF} {$ENDIF}; + +{* + * Get the touch device name as reported from the driver. + * + * \param touchID the touch device instance ID. + * \returns touch device name, or nil on failure; call SDL_GetError() for + * more information. + * + * \since This function is available since SDL 3.1.3. + } +function SDL_GetTouchDeviceName(touchID: TSDL_TouchID): PAnsiChar; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetTouchDeviceName' {$ENDIF} {$ENDIF}; + +{* + * Get the type of the given touch device. + * + * \param touchID the ID of a touch device. + * \returns touch device type. + * + * \since This function is available since SDL 3.1.3. + } +function SDL_GetTouchDeviceType(touchID: TSDL_TouchID): TSDL_TouchDeviceType; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetTouchDeviceType' {$ENDIF} {$ENDIF}; + +{* + * Get a list of active fingers for a given touch device. + * + * \param touchID the ID of a touch device. + * \param count a Pointer filled in with the number of fingers returned, can + * be nil. + * \returns a nil terminated array of SDL_Finger pointers or nil on failure; + * call SDL_GetError() for more information. This is a single + * allocation that should be freed with SDL_free() when it is no + * longer needed. + * + * \since This function is available since SDL 3.1.3. + } +function SDL_GetTouchFingers(touchID: TSDL_TouchID; count: pcint):PPSDL_Finger; cdecl; + external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_GetTouchFingers' {$ENDIF} {$ENDIF}; +