mirror of https://github.com/libsdl-org/SDL.git
Compare commits
26 Commits
777d2c85aa
...
6d9839b5a7
| Author | SHA1 | Date |
|---|---|---|
|
|
6d9839b5a7 | |
|
|
9ed83e71f6 | |
|
|
603118c340 | |
|
|
aa4f916b71 | |
|
|
6cfe211142 | |
|
|
274aa0242e | |
|
|
af8bee2dd1 | |
|
|
bbc674b9e7 | |
|
|
796961acec | |
|
|
3a6f9e01f8 | |
|
|
038a3806eb | |
|
|
e6c2649afc | |
|
|
e80d084766 | |
|
|
6aedc488d3 | |
|
|
81e3066303 | |
|
|
7d9fd48557 | |
|
|
e68f5ca99a | |
|
|
051ce0ff89 | |
|
|
5fcc83d93b | |
|
|
1bd5110ff0 | |
|
|
eb04219efe | |
|
|
d06b6e42d2 | |
|
|
c19ad189dc | |
|
|
7882e60f0e | |
|
|
e4e29b8601 | |
|
|
c8bd0e7605 |
|
|
@ -1021,7 +1021,8 @@ extern SDL_DECLSPEC void SDLCALL SDL_UnbindAudioStream(SDL_AudioStream *stream);
|
|||
/**
|
||||
* Query an audio stream for its currently-bound device.
|
||||
*
|
||||
* This reports the audio device that an audio stream is currently bound to.
|
||||
* This reports the logical 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.
|
||||
|
|
@ -1063,6 +1064,17 @@ extern SDL_DECLSPEC SDL_AudioStream * SDLCALL SDL_CreateAudioStream(const SDL_Au
|
|||
/**
|
||||
* Get the properties associated with an audio stream.
|
||||
*
|
||||
* The application can hang any data it wants here, but the following
|
||||
* properties are understood by SDL:
|
||||
*
|
||||
* - `SDL_PROP_AUDIOSTREAM_AUTO_CLEANUP_BOOLEAN`: if true (the default), the
|
||||
* stream be automatically cleaned up when the audio subsystem quits. If set
|
||||
* to false, the streams will persist beyond that. This property is ignored
|
||||
* for streams created through SDL_OpenAudioDeviceStream(), and will always
|
||||
* be cleaned up. Streams that are not cleaned up will still be unbound from
|
||||
* devices when the audio subsystem quits. This property was added in SDL
|
||||
* 3.4.0.
|
||||
*
|
||||
* \param stream the SDL_AudioStream to query.
|
||||
* \returns a valid property ID on success or 0 on failure; call
|
||||
* SDL_GetError() for more information.
|
||||
|
|
@ -1073,6 +1085,9 @@ extern SDL_DECLSPEC SDL_AudioStream * SDLCALL SDL_CreateAudioStream(const SDL_Au
|
|||
*/
|
||||
extern SDL_DECLSPEC SDL_PropertiesID SDLCALL SDL_GetAudioStreamProperties(SDL_AudioStream *stream);
|
||||
|
||||
#define SDL_PROP_AUDIOSTREAM_AUTO_CLEANUP_BOOLEAN "SDL.audiostream.auto_cleanup"
|
||||
|
||||
|
||||
/**
|
||||
* Query the current format of an audio stream.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -135,7 +135,8 @@ typedef enum SDL_EventType
|
|||
/* 0x201 was SDL_SYSWMEVENT, reserve the number for sdl2-compat */
|
||||
SDL_EVENT_WINDOW_SHOWN = 0x202, /**< Window has been shown */
|
||||
SDL_EVENT_WINDOW_HIDDEN, /**< Window has been hidden */
|
||||
SDL_EVENT_WINDOW_EXPOSED, /**< Window has been exposed and should be redrawn, and can be redrawn directly from event watchers for this event */
|
||||
SDL_EVENT_WINDOW_EXPOSED, /**< Window has been exposed and should be redrawn, and can be redrawn directly from event watchers for this event.
|
||||
data1 is 1 for live-resize expose events, 0 otherwise. */
|
||||
SDL_EVENT_WINDOW_MOVED, /**< Window has been moved to data1, data2 */
|
||||
SDL_EVENT_WINDOW_RESIZED, /**< Window has been resized to data1xdata2 */
|
||||
SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED,/**< The pixel size of the window has changed to data1xdata2 */
|
||||
|
|
|
|||
|
|
@ -2699,6 +2699,21 @@ extern "C" {
|
|||
*/
|
||||
#define SDL_HINT_MOUSE_RELATIVE_CURSOR_VISIBLE "SDL_MOUSE_RELATIVE_CURSOR_VISIBLE"
|
||||
|
||||
/**
|
||||
* A variable controlling whether SDL should leave cursor redraws to be manually
|
||||
* issued by usercode instead of automatically refreshing on state changes.
|
||||
*
|
||||
* This variable can be set to the following values:
|
||||
*
|
||||
* - "0": SDL will issue redraws automatically when focus changes (default)
|
||||
* - "1": The usercode is responsible for updating the cursor on focus change.
|
||||
*
|
||||
* This hint can be set anytime.
|
||||
*
|
||||
* \since This hint is available since SDL 3.4.0.
|
||||
*/
|
||||
#define SDL_HINT_MOUSE_CURSOR_SUSPEND_REDRAW "SDL_MOUSE_CURSOR_SUSPEND_REDRAW"
|
||||
|
||||
/**
|
||||
* A variable controlling whether mouse events should generate synthetic touch
|
||||
* events.
|
||||
|
|
|
|||
|
|
@ -1073,9 +1073,16 @@ void SDL_QuitAudio(void)
|
|||
|
||||
current_audio.impl.DeinitializeStart();
|
||||
|
||||
// Destroy any audio streams that still exist...
|
||||
while (current_audio.existing_streams) {
|
||||
SDL_DestroyAudioStream(current_audio.existing_streams);
|
||||
// Destroy any audio streams that still exist...unless app asked to keep it.
|
||||
SDL_AudioStream *next = NULL;
|
||||
for (SDL_AudioStream *i = current_audio.existing_streams; i; i = next) {
|
||||
next = i->next;
|
||||
if (i->simplified || SDL_GetBooleanProperty(i->props, SDL_PROP_AUDIOSTREAM_AUTO_CLEANUP_BOOLEAN, true)) {
|
||||
SDL_DestroyAudioStream(i);
|
||||
} else {
|
||||
i->prev = NULL;
|
||||
i->next = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_LockRWLockForWriting(current_audio.device_hash_lock);
|
||||
|
|
@ -1415,6 +1422,7 @@ static int SDLCALL RecordingAudioThread(void *devicep) // thread entry point
|
|||
typedef struct CountAudioDevicesData
|
||||
{
|
||||
int devs_seen;
|
||||
int devs_skipped;
|
||||
const int num_devices;
|
||||
SDL_AudioDeviceID *result;
|
||||
const bool recording;
|
||||
|
|
@ -1430,7 +1438,13 @@ static bool SDLCALL CountAudioDevices(void *userdata, const SDL_HashTable *table
|
|||
const bool isphysical = !!(devid & (1<<1));
|
||||
if (isphysical && (devid_recording == data->recording)) {
|
||||
SDL_assert(data->devs_seen < data->num_devices);
|
||||
data->result[data->devs_seen++] = devid;
|
||||
SDL_AudioDevice *device = (SDL_AudioDevice *) value; // this is normally risky, but we hold the device_hash_lock here.
|
||||
const bool zombie = SDL_GetAtomicInt(&device->zombie) != 0;
|
||||
if (zombie) {
|
||||
data->devs_skipped++;
|
||||
} else {
|
||||
data->result[data->devs_seen++] = devid;
|
||||
}
|
||||
}
|
||||
return true; // keep iterating.
|
||||
}
|
||||
|
|
@ -1446,10 +1460,11 @@ static SDL_AudioDeviceID *GetAudioDevices(int *count, bool recording)
|
|||
num_devices = SDL_GetAtomicInt(recording ? ¤t_audio.recording_device_count : ¤t_audio.playback_device_count);
|
||||
result = (SDL_AudioDeviceID *) SDL_malloc((num_devices + 1) * sizeof (SDL_AudioDeviceID));
|
||||
if (result) {
|
||||
CountAudioDevicesData data = { 0, num_devices, result, recording };
|
||||
CountAudioDevicesData data = { 0, 0, num_devices, result, recording };
|
||||
SDL_IterateHashTable(current_audio.device_hash, CountAudioDevices, &data);
|
||||
SDL_assert(data.devs_seen == num_devices);
|
||||
result[data.devs_seen] = 0; // null-terminated.
|
||||
SDL_assert((data.devs_seen + data.devs_skipped) == num_devices);
|
||||
num_devices = data.devs_seen; // might be less if we skipped any.
|
||||
result[num_devices] = 0; // null-terminated.
|
||||
}
|
||||
}
|
||||
SDL_UnlockRWLock(current_audio.device_hash_lock);
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@
|
|||
|
||||
#include "../SDL_sysaudio.h"
|
||||
#include "SDL_alsa_audio.h"
|
||||
#include "../../core/linux/SDL_udev.h"
|
||||
|
||||
#if SDL_ALSA_DEBUG
|
||||
#define LOGDEBUG(...) SDL_LogDebug(SDL_LOG_CATEGORY_AUDIO, "ALSA: " __VA_ARGS__)
|
||||
|
|
@ -351,21 +352,22 @@ static bool ALSA_WaitDevice(SDL_AudioDevice *device)
|
|||
const int sample_frames = device->sample_frames;
|
||||
const int fulldelay = (int) ((((Uint64) sample_frames) * 1000) / device->spec.freq);
|
||||
const int delay = SDL_clamp(fulldelay, 1, 5);
|
||||
int total_delays = 0;
|
||||
|
||||
SDL_assert(fulldelay > 0); // so the `fulldelay * 5` below produces a reasonable result.
|
||||
|
||||
while (!SDL_GetAtomicInt(&device->shutdown) && (ALSA_snd_pcm_avail(device->hidden->pcm) < sample_frames)) {
|
||||
if (total_delays >= (fulldelay * 5)) {
|
||||
// Hmm, not much we can do - abort
|
||||
SDL_LogError(SDL_LOG_CATEGORY_AUDIO, "ALSA: hardware seems to have frozen, giving up on it.");
|
||||
return false;
|
||||
} else {
|
||||
SDL_Delay(delay);
|
||||
total_delays += delay; // THIS IS NOT EXACT, but just so we don't wait forever on problems...
|
||||
while (!SDL_GetAtomicInt(&device->shutdown)) {
|
||||
const int rc = ALSA_snd_pcm_avail(device->hidden->pcm);
|
||||
if (rc < 0) {
|
||||
const int status = ALSA_snd_pcm_recover(device->hidden->pcm, rc, 0);
|
||||
if (status < 0) {
|
||||
// Hmm, not much we can do - abort
|
||||
SDL_LogError(SDL_LOG_CATEGORY_AUDIO, "ALSA wait failed (unrecoverable): %s", ALSA_snd_strerror(rc));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (rc >= sample_frames) {
|
||||
break;
|
||||
}
|
||||
SDL_Delay(delay);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -1155,7 +1157,7 @@ static bool ALSA_OpenDevice(SDL_AudioDevice *device)
|
|||
#if SDL_ALSA_DEBUG
|
||||
snd_pcm_uframes_t bufsize;
|
||||
ALSA_snd_pcm_hw_params_get_buffer_size(cfg_ctx.hwparams, &bufsize);
|
||||
SDL_LogError(SDL_LOG_CATEGORY_AUDIO,
|
||||
SDL_LogDebug(SDL_LOG_CATEGORY_AUDIO,
|
||||
"ALSA: period size = %ld, periods = %u, buffer size = %lu",
|
||||
cfg_ctx.persize, cfg_ctx.periods, bufsize);
|
||||
#endif
|
||||
|
|
@ -1444,6 +1446,65 @@ static int SDLCALL ALSA_HotplugThread(void *arg)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef SDL_USE_LIBUDEV
|
||||
|
||||
static bool udev_initialized;
|
||||
|
||||
static void ALSA_udev_callback(SDL_UDEV_deviceevent udev_type, int udev_class, const char *devpath)
|
||||
{
|
||||
if (!devpath) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (udev_type) {
|
||||
case SDL_UDEV_DEVICEADDED:
|
||||
ALSA_HotplugIteration(NULL, NULL);
|
||||
break;
|
||||
|
||||
case SDL_UDEV_DEVICEREMOVED:
|
||||
ALSA_HotplugIteration(NULL, NULL);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static bool ALSA_start_udev()
|
||||
{
|
||||
udev_initialized = SDL_UDEV_Init();
|
||||
if (udev_initialized) {
|
||||
// Set up the udev callback
|
||||
if (!SDL_UDEV_AddCallback(ALSA_udev_callback)) {
|
||||
SDL_UDEV_Quit();
|
||||
udev_initialized = false;
|
||||
}
|
||||
}
|
||||
return udev_initialized;
|
||||
}
|
||||
|
||||
static void ALSA_stop_udev()
|
||||
{
|
||||
if (udev_initialized) {
|
||||
SDL_UDEV_DelCallback(ALSA_udev_callback);
|
||||
SDL_UDEV_Quit();
|
||||
udev_initialized = false;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static bool ALSA_start_udev()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static void ALSA_stop_udev()
|
||||
{
|
||||
}
|
||||
|
||||
#endif // SDL_USE_LIBUDEV
|
||||
|
||||
static void ALSA_DetectDevices(SDL_AudioDevice **default_playback, SDL_AudioDevice **default_recording)
|
||||
{
|
||||
ALSA_guess_device_prefix();
|
||||
|
|
@ -1459,11 +1520,13 @@ static void ALSA_DetectDevices(SDL_AudioDevice **default_playback, SDL_AudioDevi
|
|||
*default_recording = SDL_AddAudioDevice(/*recording=*/true, "ALSA default recording device", NULL, (void *)&default_recording_handle);
|
||||
}
|
||||
|
||||
if (!ALSA_start_udev()) {
|
||||
#if SDL_ALSA_HOTPLUG_THREAD
|
||||
SDL_SetAtomicInt(&ALSA_hotplug_shutdown, 0);
|
||||
ALSA_hotplug_thread = SDL_CreateThread(ALSA_HotplugThread, "SDLHotplugALSA", NULL);
|
||||
// if the thread doesn't spin, oh well, you just don't get further hotplug events.
|
||||
SDL_SetAtomicInt(&ALSA_hotplug_shutdown, 0);
|
||||
ALSA_hotplug_thread = SDL_CreateThread(ALSA_HotplugThread, "SDLHotplugALSA", NULL);
|
||||
// if the thread doesn't spin, oh well, you just don't get further hotplug events.
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static void ALSA_DeinitializeStart(void)
|
||||
|
|
@ -1478,6 +1541,7 @@ static void ALSA_DeinitializeStart(void)
|
|||
ALSA_hotplug_thread = NULL;
|
||||
}
|
||||
#endif
|
||||
ALSA_stop_udev();
|
||||
|
||||
// Shutting down! Clean up any data we've gathered.
|
||||
for (dev = hotplug_devices; dev; dev = next) {
|
||||
|
|
|
|||
|
|
@ -238,6 +238,13 @@ static void SDLCALL SDL_MouseRelativeCursorVisibleChanged(void *userdata, const
|
|||
SDL_RedrawCursor(); // Update cursor visibility
|
||||
}
|
||||
|
||||
static void SDLCALL SDL_MouseCursorSuspendRedrawChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
|
||||
{
|
||||
SDL_Mouse *mouse = (SDL_Mouse *)userdata;
|
||||
|
||||
mouse->cursor_auto_redraw = !(SDL_GetStringBoolean(hint, false));
|
||||
}
|
||||
|
||||
static void SDLCALL SDL_MouseIntegerModeChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
|
||||
{
|
||||
SDL_Mouse *mouse = (SDL_Mouse *)userdata;
|
||||
|
|
@ -303,6 +310,9 @@ bool SDL_PreInitMouse(void)
|
|||
SDL_AddHintCallback(SDL_HINT_MOUSE_RELATIVE_CURSOR_VISIBLE,
|
||||
SDL_MouseRelativeCursorVisibleChanged, mouse);
|
||||
|
||||
SDL_AddHintCallback(SDL_HINT_MOUSE_CURSOR_SUSPEND_REDRAW,
|
||||
SDL_MouseCursorSuspendRedrawChanged, mouse);
|
||||
|
||||
SDL_AddHintCallback("SDL_MOUSE_INTEGER_MODE",
|
||||
SDL_MouseIntegerModeChanged, mouse);
|
||||
|
||||
|
|
@ -1173,6 +1183,9 @@ void SDL_QuitMouse(void)
|
|||
SDL_RemoveHintCallback(SDL_HINT_MOUSE_RELATIVE_CURSOR_VISIBLE,
|
||||
SDL_MouseRelativeCursorVisibleChanged, mouse);
|
||||
|
||||
SDL_RemoveHintCallback(SDL_HINT_MOUSE_CURSOR_SUSPEND_REDRAW,
|
||||
SDL_MouseCursorSuspendRedrawChanged, mouse);
|
||||
|
||||
SDL_RemoveHintCallback("SDL_MOUSE_INTEGER_MODE",
|
||||
SDL_MouseIntegerModeChanged, mouse);
|
||||
|
||||
|
|
@ -1615,11 +1628,17 @@ SDL_Cursor *SDL_CreateSystemCursor(SDL_SystemCursor id)
|
|||
return cursor;
|
||||
}
|
||||
|
||||
// Cursor redraw command used by SDL internally
|
||||
// which checks whether or not to auto-redraw.
|
||||
void SDL_RedrawCursor(void)
|
||||
{
|
||||
SDL_Mouse *mouse = SDL_GetMouse();
|
||||
SDL_Cursor *cursor;
|
||||
|
||||
if (!mouse->cursor_auto_redraw) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mouse->focus) {
|
||||
cursor = mouse->cur_cursor;
|
||||
} else {
|
||||
|
|
@ -1665,7 +1684,21 @@ bool SDL_SetCursor(SDL_Cursor *cursor)
|
|||
mouse->cur_cursor = cursor;
|
||||
}
|
||||
|
||||
SDL_RedrawCursor();
|
||||
// user-called SDL_SetCursor(NULL) are manually issued redraws,
|
||||
// so code for SDL_RedrawCursor should be mirrored here.
|
||||
if (mouse->focus) {
|
||||
cursor = mouse->cur_cursor;
|
||||
} else {
|
||||
cursor = mouse->def_cursor;
|
||||
}
|
||||
|
||||
if (mouse->focus && (!mouse->cursor_visible || (mouse->relative_mode && mouse->relative_mode_hide_cursor))) {
|
||||
cursor = NULL;
|
||||
}
|
||||
|
||||
if (mouse->ShowCursor) {
|
||||
mouse->ShowCursor(cursor);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -149,6 +149,7 @@ typedef struct
|
|||
SDL_Cursor *def_cursor;
|
||||
SDL_Cursor *cur_cursor;
|
||||
bool cursor_visible;
|
||||
bool cursor_auto_redraw;
|
||||
|
||||
// Driver-dependent data.
|
||||
void *internal;
|
||||
|
|
|
|||
|
|
@ -371,10 +371,10 @@ static const SDL_Scancode xfree86_scancode_table2[] = {
|
|||
/* 188, 0x0bc */ SDL_SCANCODE_F18, // XF86Launch9
|
||||
/* 189, 0x0bd */ SDL_SCANCODE_F19, // NoSymbol
|
||||
/* 190, 0x0be */ SDL_SCANCODE_F20, // XF86AudioMicMute
|
||||
/* 191, 0x0bf */ SDL_SCANCODE_UNKNOWN, // XF86TouchpadToggle
|
||||
/* 192, 0x0c0 */ SDL_SCANCODE_UNKNOWN, // XF86TouchpadOn
|
||||
/* 193, 0x0c1 */ SDL_SCANCODE_UNKNOWN, // XF86TouchpadOff
|
||||
/* 194, 0x0c2 */ SDL_SCANCODE_UNKNOWN, // NoSymbol
|
||||
/* 191, 0x0bf */ SDL_SCANCODE_F21, // XF86TouchpadToggle
|
||||
/* 192, 0x0c0 */ SDL_SCANCODE_F22, // XF86TouchpadOn
|
||||
/* 193, 0x0c1 */ SDL_SCANCODE_F23, // XF86TouchpadOff
|
||||
/* 194, 0x0c2 */ SDL_SCANCODE_F24, // NoSymbol
|
||||
/* 195, 0x0c3 */ SDL_SCANCODE_MODE, // Mode_switch
|
||||
/* 196, 0x0c4 */ SDL_SCANCODE_UNKNOWN, // NoSymbol
|
||||
/* 197, 0x0c5 */ SDL_SCANCODE_UNKNOWN, // NoSymbol
|
||||
|
|
|
|||
|
|
@ -71,6 +71,11 @@ extern "C" {
|
|||
#define DETACH_KERNEL_DRIVER
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:5287) /* operands are different enum types */
|
||||
#endif
|
||||
|
||||
/* Uncomment to enable the retrieval of Usage and Usage Page in
|
||||
hid_enumerate(). Warning, on platforms different from FreeBSD
|
||||
this is very invasive as it requires the detach
|
||||
|
|
@ -2144,6 +2149,10 @@ uint16_t get_usb_code_for_current_locale(void)
|
|||
return 0x0;
|
||||
}
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning (pop)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -928,13 +928,14 @@ static bool SetIMUEnabled(SDL_DriverSwitch_Context *ctx, bool enabled)
|
|||
|
||||
static bool LoadStickCalibration(SDL_DriverSwitch_Context *ctx)
|
||||
{
|
||||
Uint8 *pLeftStickCal;
|
||||
Uint8 *pRightStickCal;
|
||||
Uint8 *pLeftStickCal = NULL;
|
||||
Uint8 *pRightStickCal = NULL;
|
||||
size_t stick, axis;
|
||||
SwitchSubcommandInputPacket_t *user_reply = NULL;
|
||||
SwitchSubcommandInputPacket_t *factory_reply = NULL;
|
||||
SwitchSPIOpData_t readUserParams;
|
||||
SwitchSPIOpData_t readFactoryParams;
|
||||
Uint8 userParamsReadSuccessCount = 0;
|
||||
|
||||
// Read User Calibration Info
|
||||
readUserParams.unAddress = k_unSPIStickUserCalibrationStartOffset;
|
||||
|
|
@ -947,33 +948,46 @@ static bool LoadStickCalibration(SDL_DriverSwitch_Context *ctx)
|
|||
readFactoryParams.unAddress = k_unSPIStickFactoryCalibrationStartOffset;
|
||||
readFactoryParams.ucLength = k_unSPIStickFactoryCalibrationLength;
|
||||
|
||||
const int MAX_ATTEMPTS = 3;
|
||||
for (int attempt = 0; ; ++attempt) {
|
||||
if (!WriteSubcommand(ctx, k_eSwitchSubcommandIDs_SPIFlashRead, (uint8_t *)&readFactoryParams, sizeof(readFactoryParams), &factory_reply)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (factory_reply->stickFactoryCalibration.opData.unAddress == k_unSPIStickFactoryCalibrationStartOffset) {
|
||||
// We successfully read the calibration data
|
||||
break;
|
||||
}
|
||||
|
||||
if (attempt == MAX_ATTEMPTS) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Automatically select the user calibration if magic bytes are set
|
||||
if (user_reply && user_reply->stickUserCalibration.rgucLeftMagic[0] == 0xB2 && user_reply->stickUserCalibration.rgucLeftMagic[1] == 0xA1) {
|
||||
userParamsReadSuccessCount += 1;
|
||||
pLeftStickCal = user_reply->stickUserCalibration.rgucLeftCalibration;
|
||||
} else {
|
||||
pLeftStickCal = factory_reply->stickFactoryCalibration.rgucLeftCalibration;
|
||||
}
|
||||
|
||||
if (user_reply && user_reply->stickUserCalibration.rgucRightMagic[0] == 0xB2 && user_reply->stickUserCalibration.rgucRightMagic[1] == 0xA1) {
|
||||
userParamsReadSuccessCount += 1;
|
||||
pRightStickCal = user_reply->stickUserCalibration.rgucRightCalibration;
|
||||
} else {
|
||||
pRightStickCal = factory_reply->stickFactoryCalibration.rgucRightCalibration;
|
||||
}
|
||||
|
||||
// Only read the factory calibration info if we failed to receive the correct magic bytes
|
||||
if (userParamsReadSuccessCount < 2) {
|
||||
// Read Factory Calibration Info
|
||||
readFactoryParams.unAddress = k_unSPIStickFactoryCalibrationStartOffset;
|
||||
readFactoryParams.ucLength = k_unSPIStickFactoryCalibrationLength;
|
||||
|
||||
const int MAX_ATTEMPTS = 3;
|
||||
for (int attempt = 0;; ++attempt) {
|
||||
if (!WriteSubcommand(ctx, k_eSwitchSubcommandIDs_SPIFlashRead, (uint8_t *)&readFactoryParams, sizeof(readFactoryParams), &factory_reply)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (factory_reply->stickFactoryCalibration.opData.unAddress == k_unSPIStickFactoryCalibrationStartOffset) {
|
||||
// We successfully read the calibration data
|
||||
pLeftStickCal = factory_reply->stickFactoryCalibration.rgucLeftCalibration;
|
||||
pRightStickCal = factory_reply->stickFactoryCalibration.rgucRightCalibration;
|
||||
break;
|
||||
}
|
||||
|
||||
if (attempt == MAX_ATTEMPTS) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we still don't have calibration data, return false
|
||||
if (pLeftStickCal == NULL || pRightStickCal == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Stick calibration values are 12-bits each and are packed by bit
|
||||
|
|
@ -1109,14 +1123,17 @@ static Sint16 ApplyStickCalibration(SDL_DriverSwitch_Context *ctx, int nStick, i
|
|||
{
|
||||
sRawValue -= ctx->m_StickCalData[nStick].axis[nAxis].sCenter;
|
||||
|
||||
if (sRawValue > ctx->m_StickExtents[nStick].axis[nAxis].sMax) {
|
||||
ctx->m_StickExtents[nStick].axis[nAxis].sMax = sRawValue;
|
||||
if (sRawValue >= 0) {
|
||||
if (sRawValue > ctx->m_StickExtents[nStick].axis[nAxis].sMax) {
|
||||
ctx->m_StickExtents[nStick].axis[nAxis].sMax = sRawValue;
|
||||
}
|
||||
return (Sint16)HIDAPI_RemapVal(sRawValue, 0, ctx->m_StickExtents[nStick].axis[nAxis].sMax, 0, SDL_MAX_SINT16);
|
||||
} else {
|
||||
if (sRawValue < ctx->m_StickExtents[nStick].axis[nAxis].sMin) {
|
||||
ctx->m_StickExtents[nStick].axis[nAxis].sMin = sRawValue;
|
||||
}
|
||||
return (Sint16)HIDAPI_RemapVal(sRawValue, ctx->m_StickExtents[nStick].axis[nAxis].sMin, 0, SDL_MIN_SINT16, 0);
|
||||
}
|
||||
if (sRawValue < ctx->m_StickExtents[nStick].axis[nAxis].sMin) {
|
||||
ctx->m_StickExtents[nStick].axis[nAxis].sMin = sRawValue;
|
||||
}
|
||||
|
||||
return (Sint16)HIDAPI_RemapVal(sRawValue, ctx->m_StickExtents[nStick].axis[nAxis].sMin, ctx->m_StickExtents[nStick].axis[nAxis].sMax, SDL_MIN_SINT16, SDL_MAX_SINT16);
|
||||
}
|
||||
|
||||
static Sint16 ApplySimpleStickCalibration(SDL_DriverSwitch_Context *ctx, int nStick, int nAxis, Sint16 sRawValue)
|
||||
|
|
@ -1126,14 +1143,17 @@ static Sint16 ApplySimpleStickCalibration(SDL_DriverSwitch_Context *ctx, int nSt
|
|||
|
||||
sRawValue -= usJoystickCenter;
|
||||
|
||||
if (sRawValue > ctx->m_SimpleStickExtents[nStick].axis[nAxis].sMax) {
|
||||
ctx->m_SimpleStickExtents[nStick].axis[nAxis].sMax = sRawValue;
|
||||
if (sRawValue >= 0) {
|
||||
if (sRawValue > ctx->m_SimpleStickExtents[nStick].axis[nAxis].sMax) {
|
||||
ctx->m_SimpleStickExtents[nStick].axis[nAxis].sMax = sRawValue;
|
||||
}
|
||||
return (Sint16)HIDAPI_RemapVal(sRawValue, 0, ctx->m_SimpleStickExtents[nStick].axis[nAxis].sMax, 0, SDL_MAX_SINT16);
|
||||
} else {
|
||||
if (sRawValue < ctx->m_SimpleStickExtents[nStick].axis[nAxis].sMin) {
|
||||
ctx->m_SimpleStickExtents[nStick].axis[nAxis].sMin = sRawValue;
|
||||
}
|
||||
return (Sint16)HIDAPI_RemapVal(sRawValue, ctx->m_SimpleStickExtents[nStick].axis[nAxis].sMin, 0, SDL_MIN_SINT16, 0);
|
||||
}
|
||||
if (sRawValue < ctx->m_SimpleStickExtents[nStick].axis[nAxis].sMin) {
|
||||
ctx->m_SimpleStickExtents[nStick].axis[nAxis].sMin = sRawValue;
|
||||
}
|
||||
|
||||
return (Sint16)HIDAPI_RemapVal(sRawValue, ctx->m_SimpleStickExtents[nStick].axis[nAxis].sMin, ctx->m_SimpleStickExtents[nStick].axis[nAxis].sMax, SDL_MIN_SINT16, SDL_MAX_SINT16);
|
||||
}
|
||||
|
||||
static Uint8 RemapButton(SDL_DriverSwitch_Context *ctx, Uint8 button)
|
||||
|
|
|
|||
|
|
@ -820,6 +820,35 @@ static SceGxmTextureAddrMode TranslateAddressMode(SDL_TextureAddressMode mode)
|
|||
}
|
||||
}
|
||||
|
||||
static void ClampCliprectToViewport(SDL_Rect *clip, const SDL_Rect *viewport)
|
||||
{
|
||||
int max_x_v, max_y_v, max_x_c, max_y_c;
|
||||
|
||||
if (clip->x < 0) {
|
||||
clip->w += clip->x;
|
||||
clip->x = 0;
|
||||
}
|
||||
|
||||
if (clip->y < 0) {
|
||||
clip->h += clip->y;
|
||||
clip->y = 0;
|
||||
}
|
||||
|
||||
max_x_c = clip->x + clip->w;
|
||||
max_y_c = clip->y + clip->h;
|
||||
|
||||
max_x_v = viewport->x + viewport->w;
|
||||
max_y_v = viewport->y + viewport->h;
|
||||
|
||||
if (max_x_c > max_x_v) {
|
||||
clip->w -= (max_x_v - max_x_c);
|
||||
}
|
||||
|
||||
if (max_y_c > max_y_v) {
|
||||
clip->h -= (max_y_v - max_y_c);
|
||||
}
|
||||
}
|
||||
|
||||
static bool SetDrawState(VITA_GXM_RenderData *data, const SDL_RenderCommand *cmd)
|
||||
{
|
||||
SDL_Texture *texture = cmd->data.draw.texture;
|
||||
|
|
@ -862,9 +891,13 @@ static bool SetDrawState(VITA_GXM_RenderData *data, const SDL_RenderCommand *cmd
|
|||
data->drawstate.cliprect_enabled_dirty = false;
|
||||
}
|
||||
|
||||
if (data->drawstate.cliprect_enabled && data->drawstate.cliprect_dirty) {
|
||||
const SDL_Rect *rect = &data->drawstate.cliprect;
|
||||
set_clip_rectangle(data, rect->x, rect->y, rect->x + rect->w, rect->y + rect->h);
|
||||
if ((data->drawstate.cliprect_enabled || data->drawstate.viewport_is_set) && data->drawstate.cliprect_dirty) {
|
||||
SDL_Rect rect;
|
||||
SDL_copyp(&rect, &data->drawstate.cliprect);
|
||||
if (data->drawstate.viewport_is_set) {
|
||||
ClampCliprectToViewport(&rect, &data->drawstate.viewport);
|
||||
}
|
||||
set_clip_rectangle(data, rect.x, rect.y, rect.x + rect.w, rect.y + rect.h);
|
||||
data->drawstate.cliprect_dirty = false;
|
||||
}
|
||||
|
||||
|
|
@ -952,20 +985,31 @@ static void VITA_GXM_InvalidateCachedState(SDL_Renderer *renderer)
|
|||
static bool VITA_GXM_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize)
|
||||
{
|
||||
VITA_GXM_RenderData *data = (VITA_GXM_RenderData *)renderer->internal;
|
||||
int w, h;
|
||||
|
||||
StartDrawing(renderer);
|
||||
|
||||
data->drawstate.target = renderer->target;
|
||||
if (!data->drawstate.target) {
|
||||
int w, h;
|
||||
SDL_GetWindowSizeInPixels(renderer->window, &w, &h);
|
||||
if ((w != data->drawstate.drawablew) || (h != data->drawstate.drawableh)) {
|
||||
data->drawstate.viewport_dirty = true; // if the window dimensions changed, invalidate the current viewport, etc.
|
||||
data->drawstate.cliprect_dirty = true;
|
||||
data->drawstate.drawablew = w;
|
||||
data->drawstate.drawableh = h;
|
||||
} else {
|
||||
float fw, fh;
|
||||
if (!SDL_GetTextureSize(renderer->target, &fw, &fh)) {
|
||||
w = data->drawstate.drawablew;
|
||||
h = data->drawstate.drawableh;
|
||||
} else {
|
||||
w = (int)SDL_roundf(fw);
|
||||
h = (int)SDL_roundf(fh);
|
||||
}
|
||||
}
|
||||
|
||||
if ((w != data->drawstate.drawablew) || (h != data->drawstate.drawableh)) {
|
||||
data->drawstate.viewport_dirty = true; // if the window dimensions changed, invalidate the current viewport, etc.
|
||||
data->drawstate.cliprect_dirty = true;
|
||||
data->drawstate.drawablew = w;
|
||||
data->drawstate.drawableh = h;
|
||||
}
|
||||
|
||||
while (cmd) {
|
||||
switch (cmd->command) {
|
||||
|
||||
|
|
@ -976,6 +1020,16 @@ static bool VITA_GXM_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *
|
|||
SDL_copyp(viewport, &cmd->data.viewport.rect);
|
||||
data->drawstate.viewport_dirty = true;
|
||||
data->drawstate.cliprect_dirty = true;
|
||||
data->drawstate.viewport_is_set = viewport->x != 0 || viewport->y != 0 || viewport->w != data->drawstate.drawablew || viewport->h != data->drawstate.drawableh;
|
||||
if (!data->drawstate.cliprect_enabled) {
|
||||
if (data->drawstate.viewport_is_set) {
|
||||
SDL_copyp(&data->drawstate.cliprect, viewport);
|
||||
data->drawstate.cliprect.x = 0;
|
||||
data->drawstate.cliprect.y = 0;
|
||||
} else {
|
||||
data->drawstate.cliprect_enabled_dirty = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -983,9 +1037,15 @@ static bool VITA_GXM_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *
|
|||
case SDL_RENDERCMD_SETCLIPRECT:
|
||||
{
|
||||
const SDL_Rect *rect = &cmd->data.cliprect.rect;
|
||||
const SDL_Rect *viewport = &data->drawstate.viewport;
|
||||
if (data->drawstate.cliprect_enabled != cmd->data.cliprect.enabled) {
|
||||
data->drawstate.cliprect_enabled = cmd->data.cliprect.enabled;
|
||||
data->drawstate.cliprect_enabled_dirty = true;
|
||||
if (!data->drawstate.cliprect_enabled && data->drawstate.viewport_is_set) {
|
||||
SDL_copyp(&data->drawstate.cliprect, viewport);
|
||||
data->drawstate.cliprect.x = 0;
|
||||
data->drawstate.cliprect.y = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (SDL_memcmp(&data->drawstate.cliprect, rect, sizeof(*rect)) != 0) {
|
||||
|
|
|
|||
|
|
@ -105,6 +105,7 @@ typedef struct
|
|||
{
|
||||
SDL_Rect viewport;
|
||||
bool viewport_dirty;
|
||||
bool viewport_is_set;
|
||||
SDL_Texture *texture;
|
||||
SDL_Texture *target;
|
||||
SDL_FColor color;
|
||||
|
|
|
|||
|
|
@ -4139,7 +4139,7 @@ void SDL_OnWindowLiveResizeUpdate(SDL_Window *window)
|
|||
SDL_IterateMainCallbacks(false);
|
||||
} else {
|
||||
// Send an expose event so the application can redraw
|
||||
SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_EXPOSED, 0, 0);
|
||||
SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_EXPOSED, 1, 0);
|
||||
}
|
||||
|
||||
SDL_PumpEventMaintenance();
|
||||
|
|
|
|||
|
|
@ -588,88 +588,51 @@ static void KMSDRM_DeinitDisplays(SDL_VideoDevice *_this)
|
|||
}
|
||||
}
|
||||
|
||||
static uint32_t KMSDRM_CrtcGetPropId(uint32_t drm_fd,
|
||||
drmModeObjectPropertiesPtr props,
|
||||
char const *name)
|
||||
static bool KMSDRM_ConnectorCheckVrrCapable(uint32_t drm_fd, uint32_t output_id)
|
||||
{
|
||||
uint32_t i, prop_id = 0;
|
||||
|
||||
for (i = 0; !prop_id && i < props->count_props; ++i) {
|
||||
drmModePropertyPtr drm_prop =
|
||||
KMSDRM_drmModeGetProperty(drm_fd, props->props[i]);
|
||||
|
||||
if (!drm_prop) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (SDL_strcmp(drm_prop->name, name) == 0) {
|
||||
prop_id = drm_prop->prop_id;
|
||||
}
|
||||
|
||||
KMSDRM_drmModeFreeProperty(drm_prop);
|
||||
}
|
||||
|
||||
return prop_id;
|
||||
}
|
||||
|
||||
static bool KMSDRM_VrrPropId(uint32_t drm_fd, uint32_t crtc_id, uint32_t *vrr_prop_id)
|
||||
{
|
||||
drmModeObjectPropertiesPtr drm_props;
|
||||
|
||||
drm_props = KMSDRM_drmModeObjectGetProperties(drm_fd,
|
||||
crtc_id,
|
||||
DRM_MODE_OBJECT_CRTC);
|
||||
|
||||
if (!drm_props) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*vrr_prop_id = KMSDRM_CrtcGetPropId(drm_fd,
|
||||
drm_props,
|
||||
"VRR_ENABLED");
|
||||
|
||||
KMSDRM_drmModeFreeObjectProperties(drm_props);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool KMSDRM_ConnectorCheckVrrCapable(uint32_t drm_fd,
|
||||
uint32_t output_id,
|
||||
char const *name)
|
||||
{
|
||||
uint32_t i;
|
||||
bool found = false;
|
||||
uint64_t prop_value = 0;
|
||||
|
||||
drmModeObjectPropertiesPtr props = KMSDRM_drmModeObjectGetProperties(drm_fd,
|
||||
output_id,
|
||||
DRM_MODE_OBJECT_CONNECTOR);
|
||||
|
||||
if (!props) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (i = 0; !found && i < props->count_props; ++i) {
|
||||
drmModePropertyPtr drm_prop = KMSDRM_drmModeGetProperty(drm_fd, props->props[i]);
|
||||
|
||||
if (!drm_prop) {
|
||||
continue;
|
||||
drmModeObjectPropertiesPtr props = KMSDRM_drmModeObjectGetProperties(drm_fd, output_id, DRM_MODE_OBJECT_CONNECTOR);
|
||||
if (props) {
|
||||
for (uint32_t i = 0; !found && i < props->count_props; ++i) {
|
||||
drmModePropertyPtr prop = KMSDRM_drmModeGetProperty(drm_fd, props->props[i]);
|
||||
if (prop) {
|
||||
if (SDL_strcasecmp(prop->name, "VRR_CAPABLE") == 0) {
|
||||
prop_value = props->prop_values[i];
|
||||
found = true;
|
||||
}
|
||||
KMSDRM_drmModeFreeProperty(prop);
|
||||
}
|
||||
}
|
||||
|
||||
if (SDL_strcasecmp(drm_prop->name, name) == 0) {
|
||||
prop_value = props->prop_values[i];
|
||||
found = true;
|
||||
}
|
||||
|
||||
KMSDRM_drmModeFreeProperty(drm_prop);
|
||||
KMSDRM_drmModeFreeObjectProperties(props);
|
||||
}
|
||||
if (found) {
|
||||
return prop_value ? true : false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool KMSDRM_VrrPropId(uint32_t drm_fd, uint32_t crtc_id, uint32_t *vrr_prop_id)
|
||||
{
|
||||
bool found = false;
|
||||
drmModeObjectPropertiesPtr props = KMSDRM_drmModeObjectGetProperties(drm_fd, crtc_id, DRM_MODE_OBJECT_CRTC);
|
||||
if (props) {
|
||||
for (uint32_t i = 0; !found && i < props->count_props; ++i) {
|
||||
drmModePropertyPtr prop = KMSDRM_drmModeGetProperty(drm_fd, props->props[i]);
|
||||
if (prop) {
|
||||
if (SDL_strcmp(prop->name, "VRR_ENABLED") == 0) {
|
||||
*vrr_prop_id = prop->prop_id;
|
||||
found = true;
|
||||
}
|
||||
KMSDRM_drmModeFreeProperty(prop);
|
||||
}
|
||||
}
|
||||
KMSDRM_drmModeFreeObjectProperties(props);
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
static void KMSDRM_CrtcSetVrr(uint32_t drm_fd, uint32_t crtc_id, bool enabled)
|
||||
{
|
||||
uint32_t vrr_prop_id;
|
||||
|
|
@ -677,119 +640,67 @@ static void KMSDRM_CrtcSetVrr(uint32_t drm_fd, uint32_t crtc_id, bool enabled)
|
|||
return;
|
||||
}
|
||||
|
||||
KMSDRM_drmModeObjectSetProperty(drm_fd,
|
||||
crtc_id,
|
||||
DRM_MODE_OBJECT_CRTC,
|
||||
vrr_prop_id,
|
||||
enabled);
|
||||
KMSDRM_drmModeObjectSetProperty(drm_fd, crtc_id, DRM_MODE_OBJECT_CRTC, vrr_prop_id, enabled);
|
||||
}
|
||||
|
||||
static bool KMSDRM_CrtcGetVrr(uint32_t drm_fd, uint32_t crtc_id)
|
||||
{
|
||||
uint32_t object_prop_id, vrr_prop_id;
|
||||
drmModeObjectPropertiesPtr props;
|
||||
bool object_prop_value;
|
||||
int i;
|
||||
uint32_t vrr_prop_id = 0;
|
||||
bool found = false;
|
||||
uint64_t prop_value = 0;
|
||||
|
||||
if (!KMSDRM_VrrPropId(drm_fd, crtc_id, &vrr_prop_id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
props = KMSDRM_drmModeObjectGetProperties(drm_fd,
|
||||
crtc_id,
|
||||
DRM_MODE_OBJECT_CRTC);
|
||||
|
||||
if (!props) {
|
||||
return false;
|
||||
drmModeObjectPropertiesPtr props = KMSDRM_drmModeObjectGetProperties(drm_fd, crtc_id, DRM_MODE_OBJECT_CRTC);
|
||||
if (props) {
|
||||
for (uint32_t i = 0; !found && i < props->count_props; ++i) {
|
||||
drmModePropertyPtr prop = KMSDRM_drmModeGetProperty(drm_fd, props->props[i]);
|
||||
if (prop) {
|
||||
if (prop->prop_id == vrr_prop_id) {
|
||||
prop_value = props->prop_values[i];
|
||||
found = true;
|
||||
}
|
||||
KMSDRM_drmModeFreeProperty(prop);
|
||||
}
|
||||
}
|
||||
KMSDRM_drmModeFreeObjectProperties(props);
|
||||
}
|
||||
|
||||
for (i = 0; i < props->count_props; ++i) {
|
||||
drmModePropertyPtr drm_prop = KMSDRM_drmModeGetProperty(drm_fd, props->props[i]);
|
||||
|
||||
if (!drm_prop) {
|
||||
continue;
|
||||
}
|
||||
|
||||
object_prop_id = drm_prop->prop_id;
|
||||
object_prop_value = props->prop_values[i] ? true : false;
|
||||
|
||||
KMSDRM_drmModeFreeProperty(drm_prop);
|
||||
|
||||
if (object_prop_id == vrr_prop_id) {
|
||||
return object_prop_value;
|
||||
}
|
||||
if (found) {
|
||||
return prop_value ? true : false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool KMSDRM_OrientationPropId(uint32_t drm_fd, uint32_t crtc_id, uint32_t *orientation_prop_id)
|
||||
{
|
||||
drmModeObjectPropertiesPtr drm_props;
|
||||
|
||||
drm_props = KMSDRM_drmModeObjectGetProperties(drm_fd,
|
||||
crtc_id,
|
||||
DRM_MODE_OBJECT_CONNECTOR);
|
||||
|
||||
if (!drm_props) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*orientation_prop_id = KMSDRM_CrtcGetPropId(drm_fd,
|
||||
drm_props,
|
||||
"panel orientation");
|
||||
|
||||
KMSDRM_drmModeFreeObjectProperties(drm_props);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int KMSDRM_CrtcGetOrientation(uint32_t drm_fd, uint32_t crtc_id)
|
||||
{
|
||||
uint32_t orientation_prop_id;
|
||||
drmModeObjectPropertiesPtr props;
|
||||
int i;
|
||||
bool done = false;
|
||||
bool found = false;
|
||||
int orientation = 0;
|
||||
|
||||
if (!KMSDRM_OrientationPropId(drm_fd, crtc_id, &orientation_prop_id)) {
|
||||
return orientation;
|
||||
}
|
||||
|
||||
props = KMSDRM_drmModeObjectGetProperties(drm_fd,
|
||||
crtc_id,
|
||||
DRM_MODE_OBJECT_CONNECTOR);
|
||||
|
||||
if (!props) {
|
||||
return orientation;
|
||||
}
|
||||
|
||||
for (i = 0; i < props->count_props && !done; ++i) {
|
||||
drmModePropertyPtr drm_prop = KMSDRM_drmModeGetProperty(drm_fd, props->props[i]);
|
||||
|
||||
if (!drm_prop) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (drm_prop->prop_id == orientation_prop_id && (drm_prop->flags & DRM_MODE_PROP_ENUM)) {
|
||||
if (drm_prop->count_enums) {
|
||||
// "Normal" is the default of no rotation (0 degrees)
|
||||
if (SDL_strcmp(drm_prop->enums[0].name, "Left Side Up") == 0) {
|
||||
orientation = 90;
|
||||
} else if (SDL_strcmp(drm_prop->enums[0].name, "Upside Down") == 0) {
|
||||
orientation = 180;
|
||||
} else if (SDL_strcmp(drm_prop->enums[0].name, "Right Side Up") == 0) {
|
||||
orientation = 270;
|
||||
drmModeObjectPropertiesPtr props = KMSDRM_drmModeObjectGetProperties(drm_fd, crtc_id, DRM_MODE_OBJECT_CONNECTOR);
|
||||
if (props) {
|
||||
for (uint32_t i = 0; !found && i < props->count_props; ++i) {
|
||||
drmModePropertyPtr prop = KMSDRM_drmModeGetProperty(drm_fd, props->props[i]);
|
||||
if (prop) {
|
||||
if (SDL_strcasecmp(prop->name, "panel orientation") == 0 && (prop->flags & DRM_MODE_PROP_ENUM)) {
|
||||
if (prop->count_enums) {
|
||||
// "Normal" is the default of no rotation (0 degrees)
|
||||
if (SDL_strcmp(prop->enums[0].name, "Left Side Up") == 0) {
|
||||
orientation = 90;
|
||||
} else if (SDL_strcmp(prop->enums[0].name, "Upside Down") == 0) {
|
||||
orientation = 180;
|
||||
} else if (SDL_strcmp(prop->enums[0].name, "Right Side Up") == 0) {
|
||||
orientation = 270;
|
||||
}
|
||||
}
|
||||
found = true;
|
||||
}
|
||||
KMSDRM_drmModeFreeProperty(prop);
|
||||
}
|
||||
|
||||
done = true;
|
||||
}
|
||||
|
||||
KMSDRM_drmModeFreeProperty(drm_prop);
|
||||
KMSDRM_drmModeFreeObjectProperties(props);
|
||||
}
|
||||
|
||||
KMSDRM_drmModeFreeObjectProperties(props);
|
||||
|
||||
return orientation;
|
||||
}
|
||||
|
||||
|
|
@ -964,7 +875,7 @@ static void KMSDRM_AddDisplay(SDL_VideoDevice *_this, drmModeConnector *connecto
|
|||
// save previous vrr state
|
||||
dispdata->saved_vrr = KMSDRM_CrtcGetVrr(viddata->drm_fd, crtc->crtc_id);
|
||||
// try to enable vrr
|
||||
if (KMSDRM_ConnectorCheckVrrCapable(viddata->drm_fd, connector->connector_id, "VRR_CAPABLE")) {
|
||||
if (KMSDRM_ConnectorCheckVrrCapable(viddata->drm_fd, connector->connector_id)) {
|
||||
SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Enabling VRR");
|
||||
KMSDRM_CrtcSetVrr(viddata->drm_fd, crtc->crtc_id, true);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -701,6 +701,10 @@ static void WIN_HandleRawMouseInput(Uint64 timestamp, SDL_VideoData *data, HANDL
|
|||
float fAmount = (float)amount / WHEEL_DELTA;
|
||||
SDL_SendMouseWheel(WIN_GetEventTimestamp(), window, mouseID, fAmount, 0.0f, SDL_MOUSEWHEEL_NORMAL);
|
||||
}
|
||||
|
||||
/* Invalidate the mouse button flags. If we don't do this then disabling raw input
|
||||
will cause held down mouse buttons to persist when released. */
|
||||
windowdata->mouse_button_flags = (WPARAM)-1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -279,6 +279,9 @@ static void GAMEINPUT_InitialMouseReading(WIN_GameInputData *data, SDL_Window *w
|
|||
bool down = ((state.buttons & mask) != 0);
|
||||
SDL_SendMouseButton(timestamp, window, mouseID, GAMEINPUT_button_map[i], down);
|
||||
}
|
||||
|
||||
// Invalidate mouse button flags
|
||||
window->internal->mouse_button_flags = (WPARAM)-1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -308,6 +311,9 @@ static void GAMEINPUT_HandleMouseDelta(WIN_GameInputData *data, SDL_Window *wind
|
|||
SDL_SendMouseButton(timestamp, window, mouseID, GAMEINPUT_button_map[i], down);
|
||||
}
|
||||
}
|
||||
|
||||
// Invalidate mouse button flags
|
||||
window->internal->mouse_button_flags = (WPARAM)-1;
|
||||
}
|
||||
if (delta.wheelX || delta.wheelY) {
|
||||
float fAmountX = (float)delta.wheelX / WHEEL_DELTA;
|
||||
|
|
|
|||
|
|
@ -420,7 +420,7 @@ add_sdl_test_executable(testdialog SOURCES testdialog.c)
|
|||
add_sdl_test_executable(testtime SOURCES testtime.c)
|
||||
add_sdl_test_executable(testmanymouse SOURCES testmanymouse.c)
|
||||
add_sdl_test_executable(testmodal SOURCES testmodal.c)
|
||||
add_sdl_test_executable(testtray SOURCES testtray.c)
|
||||
add_sdl_test_executable(testtray NEEDS_RESOURCES TESTUTILS SOURCES testtray.c)
|
||||
|
||||
|
||||
add_sdl_test_executable(testprocess
|
||||
|
|
|
|||
|
|
@ -679,6 +679,16 @@ void SetupVulkanRenderProperties(VulkanVideoContext *context, SDL_PropertiesID p
|
|||
SDL_SetNumberProperty(props, SDL_PROP_RENDERER_CREATE_VULKAN_GRAPHICS_QUEUE_FAMILY_INDEX_NUMBER, context->graphicsQueueFamilyIndex);
|
||||
}
|
||||
|
||||
#if LIBAVUTIL_VERSION_MAJOR >= 59
|
||||
static void AddQueueFamily(AVVulkanDeviceContext *ctx, int idx, int num, VkQueueFlagBits flags)
|
||||
{
|
||||
AVVulkanDeviceQueueFamily *entry = &ctx->qf[ctx->nb_qf++];
|
||||
entry->idx = idx;
|
||||
entry->num = num;
|
||||
entry->flags = flags;
|
||||
}
|
||||
#endif /* LIBAVUTIL_VERSION_MAJOR */
|
||||
|
||||
void SetupVulkanDeviceContextData(VulkanVideoContext *context, AVVulkanDeviceContext *ctx)
|
||||
{
|
||||
ctx->get_proc_addr = context->vkGetInstanceProcAddr;
|
||||
|
|
@ -690,6 +700,12 @@ void SetupVulkanDeviceContextData(VulkanVideoContext *context, AVVulkanDeviceCon
|
|||
ctx->nb_enabled_inst_extensions = context->instanceExtensionsCount;
|
||||
ctx->enabled_dev_extensions = context->deviceExtensions;
|
||||
ctx->nb_enabled_dev_extensions = context->deviceExtensionsCount;
|
||||
#if LIBAVUTIL_VERSION_MAJOR >= 59
|
||||
AddQueueFamily(ctx, context->graphicsQueueFamilyIndex, context->graphicsQueueCount, VK_QUEUE_GRAPHICS_BIT);
|
||||
AddQueueFamily(ctx, context->transferQueueFamilyIndex, context->transferQueueCount, VK_QUEUE_TRANSFER_BIT);
|
||||
AddQueueFamily(ctx, context->computeQueueFamilyIndex, context->computeQueueCount, VK_QUEUE_COMPUTE_BIT);
|
||||
AddQueueFamily(ctx, context->decodeQueueFamilyIndex, context->decodeQueueCount, VK_QUEUE_VIDEO_DECODE_BIT_KHR);
|
||||
#else
|
||||
ctx->queue_family_index = context->graphicsQueueFamilyIndex;
|
||||
ctx->nb_graphics_queues = context->graphicsQueueCount;
|
||||
ctx->queue_family_tx_index = context->transferQueueFamilyIndex;
|
||||
|
|
@ -700,6 +716,7 @@ void SetupVulkanDeviceContextData(VulkanVideoContext *context, AVVulkanDeviceCon
|
|||
ctx->nb_encode_queues = 0;
|
||||
ctx->queue_family_decode_index = context->decodeQueueFamilyIndex;
|
||||
ctx->nb_decode_queues = context->decodeQueueCount;
|
||||
#endif /* LIBAVUTIL_VERSION_MAJOR */
|
||||
}
|
||||
|
||||
static int CreateCommandBuffers(VulkanVideoContext *context, SDL_Renderer *renderer)
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#include "testutils.h"
|
||||
#include <SDL3/SDL.h>
|
||||
#include <SDL3/SDL_main.h>
|
||||
#include <SDL3/SDL_test.h>
|
||||
|
|
@ -520,14 +521,17 @@ int main(int argc, char **argv)
|
|||
goto quit;
|
||||
}
|
||||
|
||||
/* TODO: Resource paths? */
|
||||
SDL_Surface *icon = SDL_LoadBMP("../test/sdl-test_round.bmp");
|
||||
char *icon1filename = GetResourceFilename(NULL, "sdl-test_round.bmp");
|
||||
SDL_Surface *icon = SDL_LoadBMP(icon1filename);
|
||||
SDL_free(icon1filename);
|
||||
|
||||
if (!icon) {
|
||||
SDL_Log("Couldn't load icon 1, proceeding without: %s", SDL_GetError());
|
||||
}
|
||||
|
||||
SDL_Surface *icon2 = SDL_LoadBMP("../test/speaker.bmp");
|
||||
char *icon2filename = GetResourceFilename(NULL, "speaker.bmp");
|
||||
SDL_Surface *icon2 = SDL_LoadBMP(icon2filename);
|
||||
SDL_free(icon2filename);
|
||||
|
||||
if (!icon2) {
|
||||
SDL_Log("Couldn't load icon 2, proceeding without: %s", SDL_GetError());
|
||||
|
|
|
|||
Loading…
Reference in New Issue